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 "igt.h"
25*d83cc019SAndroid Build Coastguard Worker #include "igt_dummyload.h"
26*d83cc019SAndroid Build Coastguard Worker
27*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Basic sanity check of execbuf-ioctl relocations.");
28*d83cc019SAndroid Build Coastguard Worker
29*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_SHIFT (13)
30*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_BSD_MASK (3 << LOCAL_I915_EXEC_BSD_SHIFT)
31*d83cc019SAndroid Build Coastguard Worker
32*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_NO_RELOC (1<<11)
33*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
34*d83cc019SAndroid Build Coastguard Worker
35*d83cc019SAndroid Build Coastguard Worker #define ENGINE_MASK (I915_EXEC_RING_MASK | LOCAL_I915_EXEC_BSD_MASK)
36*d83cc019SAndroid Build Coastguard Worker
find_last_set(uint64_t x)37*d83cc019SAndroid Build Coastguard Worker static uint32_t find_last_set(uint64_t x)
38*d83cc019SAndroid Build Coastguard Worker {
39*d83cc019SAndroid Build Coastguard Worker uint32_t i = 0;
40*d83cc019SAndroid Build Coastguard Worker while (x) {
41*d83cc019SAndroid Build Coastguard Worker x >>= 1;
42*d83cc019SAndroid Build Coastguard Worker i++;
43*d83cc019SAndroid Build Coastguard Worker }
44*d83cc019SAndroid Build Coastguard Worker return i;
45*d83cc019SAndroid Build Coastguard Worker }
46*d83cc019SAndroid Build Coastguard Worker
write_dword(int fd,uint32_t target_handle,uint64_t target_offset,uint32_t value)47*d83cc019SAndroid Build Coastguard Worker static void write_dword(int fd,
48*d83cc019SAndroid Build Coastguard Worker uint32_t target_handle,
49*d83cc019SAndroid Build Coastguard Worker uint64_t target_offset,
50*d83cc019SAndroid Build Coastguard Worker uint32_t value)
51*d83cc019SAndroid Build Coastguard Worker {
52*d83cc019SAndroid Build Coastguard Worker int gen = intel_gen(intel_get_drm_devid(fd));
53*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
54*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj[2];
55*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc;
56*d83cc019SAndroid Build Coastguard Worker uint32_t buf[16];
57*d83cc019SAndroid Build Coastguard Worker int i;
58*d83cc019SAndroid Build Coastguard Worker
59*d83cc019SAndroid Build Coastguard Worker memset(obj, 0, sizeof(obj));
60*d83cc019SAndroid Build Coastguard Worker obj[0].handle = target_handle;
61*d83cc019SAndroid Build Coastguard Worker obj[1].handle = gem_create(fd, 4096);
62*d83cc019SAndroid Build Coastguard Worker
63*d83cc019SAndroid Build Coastguard Worker i = 0;
64*d83cc019SAndroid Build Coastguard Worker buf[i++] = MI_STORE_DWORD_IMM | (gen < 6 ? 1<<22 : 0);
65*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
66*d83cc019SAndroid Build Coastguard Worker buf[i++] = target_offset;
67*d83cc019SAndroid Build Coastguard Worker buf[i++] = target_offset >> 32;
68*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
69*d83cc019SAndroid Build Coastguard Worker buf[i++] = 0;
70*d83cc019SAndroid Build Coastguard Worker buf[i++] = target_offset;
71*d83cc019SAndroid Build Coastguard Worker } else {
72*d83cc019SAndroid Build Coastguard Worker buf[i-1]--;
73*d83cc019SAndroid Build Coastguard Worker buf[i++] = target_offset;
74*d83cc019SAndroid Build Coastguard Worker }
75*d83cc019SAndroid Build Coastguard Worker buf[i++] = value;
76*d83cc019SAndroid Build Coastguard Worker buf[i++] = MI_BATCH_BUFFER_END;
77*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[1].handle, 0, buf, sizeof(buf));
78*d83cc019SAndroid Build Coastguard Worker
79*d83cc019SAndroid Build Coastguard Worker memset(&reloc, 0, sizeof(reloc));
80*d83cc019SAndroid Build Coastguard Worker if (gen >= 8 || gen < 4)
81*d83cc019SAndroid Build Coastguard Worker reloc.offset = sizeof(uint32_t);
82*d83cc019SAndroid Build Coastguard Worker else
83*d83cc019SAndroid Build Coastguard Worker reloc.offset = 2*sizeof(uint32_t);
84*d83cc019SAndroid Build Coastguard Worker reloc.target_handle = target_handle;
85*d83cc019SAndroid Build Coastguard Worker reloc.delta = target_offset;
86*d83cc019SAndroid Build Coastguard Worker reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
87*d83cc019SAndroid Build Coastguard Worker reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
88*d83cc019SAndroid Build Coastguard Worker
89*d83cc019SAndroid Build Coastguard Worker obj[1].relocation_count = 1;
90*d83cc019SAndroid Build Coastguard Worker obj[1].relocs_ptr = to_user_pointer(&reloc);
91*d83cc019SAndroid Build Coastguard Worker
92*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
93*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(obj);
94*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
95*d83cc019SAndroid Build Coastguard Worker execbuf.flags = I915_EXEC_SECURE;
96*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
97*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[1].handle);
98*d83cc019SAndroid Build Coastguard Worker }
99*d83cc019SAndroid Build Coastguard Worker
100*d83cc019SAndroid Build Coastguard Worker enum mode { MEM, CPU, WC, GTT };
101*d83cc019SAndroid Build Coastguard Worker #define RO 0x100
from_mmap(int fd,uint64_t size,enum mode mode)102*d83cc019SAndroid Build Coastguard Worker static void from_mmap(int fd, uint64_t size, enum mode mode)
103*d83cc019SAndroid Build Coastguard Worker {
104*d83cc019SAndroid Build Coastguard Worker uint32_t bbe = MI_BATCH_BUFFER_END;
105*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
106*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj;
107*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry *relocs;
108*d83cc019SAndroid Build Coastguard Worker uint32_t reloc_handle;
109*d83cc019SAndroid Build Coastguard Worker uint64_t value;
110*d83cc019SAndroid Build Coastguard Worker uint64_t max, i;
111*d83cc019SAndroid Build Coastguard Worker int retry = 2;
112*d83cc019SAndroid Build Coastguard Worker
113*d83cc019SAndroid Build Coastguard Worker /* Worst case is that the kernel has to copy the entire incoming
114*d83cc019SAndroid Build Coastguard Worker * reloc[], so double the memory requirements.
115*d83cc019SAndroid Build Coastguard Worker */
116*d83cc019SAndroid Build Coastguard Worker intel_require_memory(2, size, CHECK_RAM);
117*d83cc019SAndroid Build Coastguard Worker
118*d83cc019SAndroid Build Coastguard Worker memset(&obj, 0, sizeof(obj));
119*d83cc019SAndroid Build Coastguard Worker obj.handle = gem_create(fd, 4096);
120*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
121*d83cc019SAndroid Build Coastguard Worker
122*d83cc019SAndroid Build Coastguard Worker max = size / sizeof(*relocs);
123*d83cc019SAndroid Build Coastguard Worker switch (mode & ~RO) {
124*d83cc019SAndroid Build Coastguard Worker case MEM:
125*d83cc019SAndroid Build Coastguard Worker relocs = mmap(0, size,
126*d83cc019SAndroid Build Coastguard Worker PROT_WRITE, MAP_PRIVATE | MAP_ANON,
127*d83cc019SAndroid Build Coastguard Worker -1, 0);
128*d83cc019SAndroid Build Coastguard Worker igt_assert(relocs != (void *)-1);
129*d83cc019SAndroid Build Coastguard Worker break;
130*d83cc019SAndroid Build Coastguard Worker case GTT:
131*d83cc019SAndroid Build Coastguard Worker reloc_handle = gem_create(fd, size);
132*d83cc019SAndroid Build Coastguard Worker relocs = gem_mmap__gtt(fd, reloc_handle, size, PROT_WRITE);
133*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, reloc_handle,
134*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
135*d83cc019SAndroid Build Coastguard Worker gem_close(fd, reloc_handle);
136*d83cc019SAndroid Build Coastguard Worker break;
137*d83cc019SAndroid Build Coastguard Worker case CPU:
138*d83cc019SAndroid Build Coastguard Worker reloc_handle = gem_create(fd, size);
139*d83cc019SAndroid Build Coastguard Worker relocs = gem_mmap__cpu(fd, reloc_handle, 0, size, PROT_WRITE);
140*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, reloc_handle,
141*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
142*d83cc019SAndroid Build Coastguard Worker gem_close(fd, reloc_handle);
143*d83cc019SAndroid Build Coastguard Worker break;
144*d83cc019SAndroid Build Coastguard Worker case WC:
145*d83cc019SAndroid Build Coastguard Worker reloc_handle = gem_create(fd, size);
146*d83cc019SAndroid Build Coastguard Worker relocs = gem_mmap__wc(fd, reloc_handle, 0, size, PROT_WRITE);
147*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, reloc_handle,
148*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC);
149*d83cc019SAndroid Build Coastguard Worker gem_close(fd, reloc_handle);
150*d83cc019SAndroid Build Coastguard Worker break;
151*d83cc019SAndroid Build Coastguard Worker }
152*d83cc019SAndroid Build Coastguard Worker
153*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < max; i++) {
154*d83cc019SAndroid Build Coastguard Worker relocs[i].target_handle = obj.handle;
155*d83cc019SAndroid Build Coastguard Worker relocs[i].presumed_offset = ~0ull;
156*d83cc019SAndroid Build Coastguard Worker relocs[i].offset = 1024;
157*d83cc019SAndroid Build Coastguard Worker relocs[i].delta = i;
158*d83cc019SAndroid Build Coastguard Worker relocs[i].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
159*d83cc019SAndroid Build Coastguard Worker relocs[i].write_domain = 0;
160*d83cc019SAndroid Build Coastguard Worker }
161*d83cc019SAndroid Build Coastguard Worker obj.relocation_count = max;
162*d83cc019SAndroid Build Coastguard Worker obj.relocs_ptr = to_user_pointer(relocs);
163*d83cc019SAndroid Build Coastguard Worker
164*d83cc019SAndroid Build Coastguard Worker if (mode & RO)
165*d83cc019SAndroid Build Coastguard Worker mprotect(relocs, size, PROT_READ);
166*d83cc019SAndroid Build Coastguard Worker
167*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
168*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&obj);
169*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
170*d83cc019SAndroid Build Coastguard Worker while (relocs[0].presumed_offset == ~0ull && retry--)
171*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
172*d83cc019SAndroid Build Coastguard Worker gem_read(fd, obj.handle, 1024, &value, sizeof(value));
173*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj.handle);
174*d83cc019SAndroid Build Coastguard Worker
175*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(value, obj.offset + max - 1);
176*d83cc019SAndroid Build Coastguard Worker if (relocs[0].presumed_offset != ~0ull) {
177*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < max; i++)
178*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(relocs[i].presumed_offset,
179*d83cc019SAndroid Build Coastguard Worker obj.offset);
180*d83cc019SAndroid Build Coastguard Worker }
181*d83cc019SAndroid Build Coastguard Worker munmap(relocs, size);
182*d83cc019SAndroid Build Coastguard Worker }
183*d83cc019SAndroid Build Coastguard Worker
from_gpu(int fd)184*d83cc019SAndroid Build Coastguard Worker static void from_gpu(int fd)
185*d83cc019SAndroid Build Coastguard Worker {
186*d83cc019SAndroid Build Coastguard Worker uint32_t bbe = MI_BATCH_BUFFER_END;
187*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
188*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj;
189*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry *relocs;
190*d83cc019SAndroid Build Coastguard Worker uint32_t reloc_handle;
191*d83cc019SAndroid Build Coastguard Worker uint64_t value;
192*d83cc019SAndroid Build Coastguard Worker
193*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, 0));
194*d83cc019SAndroid Build Coastguard Worker
195*d83cc019SAndroid Build Coastguard Worker memset(&obj, 0, sizeof(obj));
196*d83cc019SAndroid Build Coastguard Worker obj.handle = gem_create(fd, 4096);
197*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
198*d83cc019SAndroid Build Coastguard Worker
199*d83cc019SAndroid Build Coastguard Worker reloc_handle = gem_create(fd, 4096);
200*d83cc019SAndroid Build Coastguard Worker write_dword(fd,
201*d83cc019SAndroid Build Coastguard Worker reloc_handle,
202*d83cc019SAndroid Build Coastguard Worker offsetof(struct drm_i915_gem_relocation_entry,
203*d83cc019SAndroid Build Coastguard Worker target_handle),
204*d83cc019SAndroid Build Coastguard Worker obj.handle);
205*d83cc019SAndroid Build Coastguard Worker write_dword(fd,
206*d83cc019SAndroid Build Coastguard Worker reloc_handle,
207*d83cc019SAndroid Build Coastguard Worker offsetof(struct drm_i915_gem_relocation_entry,
208*d83cc019SAndroid Build Coastguard Worker offset),
209*d83cc019SAndroid Build Coastguard Worker 1024);
210*d83cc019SAndroid Build Coastguard Worker write_dword(fd,
211*d83cc019SAndroid Build Coastguard Worker reloc_handle,
212*d83cc019SAndroid Build Coastguard Worker offsetof(struct drm_i915_gem_relocation_entry,
213*d83cc019SAndroid Build Coastguard Worker read_domains),
214*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_INSTRUCTION);
215*d83cc019SAndroid Build Coastguard Worker
216*d83cc019SAndroid Build Coastguard Worker relocs = gem_mmap__cpu(fd, reloc_handle, 0, 4096, PROT_READ);
217*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, reloc_handle,
218*d83cc019SAndroid Build Coastguard Worker I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
219*d83cc019SAndroid Build Coastguard Worker gem_close(fd, reloc_handle);
220*d83cc019SAndroid Build Coastguard Worker
221*d83cc019SAndroid Build Coastguard Worker obj.relocation_count = 1;
222*d83cc019SAndroid Build Coastguard Worker obj.relocs_ptr = to_user_pointer(relocs);
223*d83cc019SAndroid Build Coastguard Worker
224*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
225*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&obj);
226*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
227*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
228*d83cc019SAndroid Build Coastguard Worker gem_read(fd, obj.handle, 1024, &value, sizeof(value));
229*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj.handle);
230*d83cc019SAndroid Build Coastguard Worker
231*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(value, obj.offset);
232*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(relocs->presumed_offset, obj.offset);
233*d83cc019SAndroid Build Coastguard Worker munmap(relocs, 4096);
234*d83cc019SAndroid Build Coastguard Worker }
235*d83cc019SAndroid Build Coastguard Worker
check_bo(int fd,uint32_t handle)236*d83cc019SAndroid Build Coastguard Worker static void check_bo(int fd, uint32_t handle)
237*d83cc019SAndroid Build Coastguard Worker {
238*d83cc019SAndroid Build Coastguard Worker uint32_t *map;
239*d83cc019SAndroid Build Coastguard Worker int i;
240*d83cc019SAndroid Build Coastguard Worker
241*d83cc019SAndroid Build Coastguard Worker igt_debug("Verifying result\n");
242*d83cc019SAndroid Build Coastguard Worker map = gem_mmap__cpu(fd, handle, 0, 4096, PROT_READ);
243*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, handle, I915_GEM_DOMAIN_CPU, 0);
244*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < 1024; i++)
245*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(map[i], i);
246*d83cc019SAndroid Build Coastguard Worker munmap(map, 4096);
247*d83cc019SAndroid Build Coastguard Worker }
248*d83cc019SAndroid Build Coastguard Worker
active(int fd,unsigned engine)249*d83cc019SAndroid Build Coastguard Worker static void active(int fd, unsigned engine)
250*d83cc019SAndroid Build Coastguard Worker {
251*d83cc019SAndroid Build Coastguard Worker const int gen = intel_gen(intel_get_drm_devid(fd));
252*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc;
253*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj[2];
254*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
255*d83cc019SAndroid Build Coastguard Worker unsigned engines[16];
256*d83cc019SAndroid Build Coastguard Worker unsigned nengine;
257*d83cc019SAndroid Build Coastguard Worker int pass;
258*d83cc019SAndroid Build Coastguard Worker
259*d83cc019SAndroid Build Coastguard Worker nengine = 0;
260*d83cc019SAndroid Build Coastguard Worker if (engine == ALL_ENGINES) {
261*d83cc019SAndroid Build Coastguard Worker for_each_physical_engine(fd, engine) {
262*d83cc019SAndroid Build Coastguard Worker if (gem_can_store_dword(fd, engine))
263*d83cc019SAndroid Build Coastguard Worker engines[nengine++] = engine;
264*d83cc019SAndroid Build Coastguard Worker }
265*d83cc019SAndroid Build Coastguard Worker } else {
266*d83cc019SAndroid Build Coastguard Worker igt_require(gem_has_ring(fd, engine));
267*d83cc019SAndroid Build Coastguard Worker igt_require(gem_can_store_dword(fd, engine));
268*d83cc019SAndroid Build Coastguard Worker engines[nengine++] = engine;
269*d83cc019SAndroid Build Coastguard Worker }
270*d83cc019SAndroid Build Coastguard Worker igt_require(nengine);
271*d83cc019SAndroid Build Coastguard Worker
272*d83cc019SAndroid Build Coastguard Worker memset(obj, 0, sizeof(obj));
273*d83cc019SAndroid Build Coastguard Worker obj[0].handle = gem_create(fd, 4096);
274*d83cc019SAndroid Build Coastguard Worker obj[1].handle = gem_create(fd, 64*1024);
275*d83cc019SAndroid Build Coastguard Worker obj[1].relocs_ptr = to_user_pointer(&reloc);
276*d83cc019SAndroid Build Coastguard Worker obj[1].relocation_count = 1;
277*d83cc019SAndroid Build Coastguard Worker
278*d83cc019SAndroid Build Coastguard Worker memset(&reloc, 0, sizeof(reloc));
279*d83cc019SAndroid Build Coastguard Worker reloc.offset = sizeof(uint32_t);
280*d83cc019SAndroid Build Coastguard Worker reloc.target_handle = obj[0].handle;
281*d83cc019SAndroid Build Coastguard Worker if (gen < 8 && gen >= 4)
282*d83cc019SAndroid Build Coastguard Worker reloc.offset += sizeof(uint32_t);
283*d83cc019SAndroid Build Coastguard Worker reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
284*d83cc019SAndroid Build Coastguard Worker reloc.write_domain = I915_GEM_DOMAIN_INSTRUCTION;
285*d83cc019SAndroid Build Coastguard Worker
286*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
287*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(obj);
288*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
289*d83cc019SAndroid Build Coastguard Worker if (gen < 6)
290*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= I915_EXEC_SECURE;
291*d83cc019SAndroid Build Coastguard Worker
292*d83cc019SAndroid Build Coastguard Worker for (pass = 0; pass < 1024; pass++) {
293*d83cc019SAndroid Build Coastguard Worker uint32_t batch[16];
294*d83cc019SAndroid Build Coastguard Worker int i = 0;
295*d83cc019SAndroid Build Coastguard Worker batch[i] = MI_STORE_DWORD_IMM | (gen < 6 ? 1 << 22 : 0);
296*d83cc019SAndroid Build Coastguard Worker if (gen >= 8) {
297*d83cc019SAndroid Build Coastguard Worker batch[++i] = 0;
298*d83cc019SAndroid Build Coastguard Worker batch[++i] = 0;
299*d83cc019SAndroid Build Coastguard Worker } else if (gen >= 4) {
300*d83cc019SAndroid Build Coastguard Worker batch[++i] = 0;
301*d83cc019SAndroid Build Coastguard Worker batch[++i] = 0;
302*d83cc019SAndroid Build Coastguard Worker } else {
303*d83cc019SAndroid Build Coastguard Worker batch[i]--;
304*d83cc019SAndroid Build Coastguard Worker batch[++i] = 0;
305*d83cc019SAndroid Build Coastguard Worker }
306*d83cc019SAndroid Build Coastguard Worker batch[++i] = pass;
307*d83cc019SAndroid Build Coastguard Worker batch[++i] = MI_BATCH_BUFFER_END;
308*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[1].handle, pass*sizeof(batch),
309*d83cc019SAndroid Build Coastguard Worker batch, sizeof(batch));
310*d83cc019SAndroid Build Coastguard Worker }
311*d83cc019SAndroid Build Coastguard Worker
312*d83cc019SAndroid Build Coastguard Worker for (pass = 0; pass < 1024; pass++) {
313*d83cc019SAndroid Build Coastguard Worker reloc.delta = 4*pass;
314*d83cc019SAndroid Build Coastguard Worker reloc.presumed_offset = -1;
315*d83cc019SAndroid Build Coastguard Worker execbuf.flags &= ~ENGINE_MASK;
316*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= engines[rand() % nengine];
317*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
318*d83cc019SAndroid Build Coastguard Worker execbuf.batch_start_offset += 64;
319*d83cc019SAndroid Build Coastguard Worker reloc.offset += 64;
320*d83cc019SAndroid Build Coastguard Worker }
321*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[1].handle);
322*d83cc019SAndroid Build Coastguard Worker
323*d83cc019SAndroid Build Coastguard Worker check_bo(fd, obj[0].handle);
324*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[0].handle);
325*d83cc019SAndroid Build Coastguard Worker }
326*d83cc019SAndroid Build Coastguard Worker
has_64b_reloc(int fd)327*d83cc019SAndroid Build Coastguard Worker static bool has_64b_reloc(int fd)
328*d83cc019SAndroid Build Coastguard Worker {
329*d83cc019SAndroid Build Coastguard Worker return intel_gen(intel_get_drm_devid(fd)) >= 8;
330*d83cc019SAndroid Build Coastguard Worker }
331*d83cc019SAndroid Build Coastguard Worker
332*d83cc019SAndroid Build Coastguard Worker #define NORELOC 1
333*d83cc019SAndroid Build Coastguard Worker #define ACTIVE 2
334*d83cc019SAndroid Build Coastguard Worker #define HANG 4
basic_reloc(int fd,unsigned before,unsigned after,unsigned flags)335*d83cc019SAndroid Build Coastguard Worker static void basic_reloc(int fd, unsigned before, unsigned after, unsigned flags)
336*d83cc019SAndroid Build Coastguard Worker {
337*d83cc019SAndroid Build Coastguard Worker #define OBJSZ 8192
338*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc;
339*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj;
340*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
341*d83cc019SAndroid Build Coastguard Worker uint64_t address_mask = has_64b_reloc(fd) ? ~(uint64_t)0 : ~(uint32_t)0;
342*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
343*d83cc019SAndroid Build Coastguard Worker unsigned int reloc_offset;
344*d83cc019SAndroid Build Coastguard Worker
345*d83cc019SAndroid Build Coastguard Worker memset(&obj, 0, sizeof(obj));
346*d83cc019SAndroid Build Coastguard Worker obj.handle = gem_create(fd, OBJSZ);
347*d83cc019SAndroid Build Coastguard Worker obj.relocs_ptr = to_user_pointer(&reloc);
348*d83cc019SAndroid Build Coastguard Worker obj.relocation_count = 1;
349*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
350*d83cc019SAndroid Build Coastguard Worker
351*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
352*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&obj);
353*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
354*d83cc019SAndroid Build Coastguard Worker if (flags & NORELOC)
355*d83cc019SAndroid Build Coastguard Worker execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
356*d83cc019SAndroid Build Coastguard Worker
357*d83cc019SAndroid Build Coastguard Worker for (reloc_offset = 4096 - 8; reloc_offset <= 4096 + 8; reloc_offset += 4) {
358*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin = NULL;
359*d83cc019SAndroid Build Coastguard Worker uint32_t trash = 0;
360*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
361*d83cc019SAndroid Build Coastguard Worker
362*d83cc019SAndroid Build Coastguard Worker obj.offset = -1;
363*d83cc019SAndroid Build Coastguard Worker
364*d83cc019SAndroid Build Coastguard Worker memset(&reloc, 0, sizeof(reloc));
365*d83cc019SAndroid Build Coastguard Worker reloc.offset = reloc_offset;
366*d83cc019SAndroid Build Coastguard Worker reloc.target_handle = obj.handle;
367*d83cc019SAndroid Build Coastguard Worker reloc.read_domains = I915_GEM_DOMAIN_INSTRUCTION;
368*d83cc019SAndroid Build Coastguard Worker reloc.presumed_offset = -1;
369*d83cc019SAndroid Build Coastguard Worker
370*d83cc019SAndroid Build Coastguard Worker if (before) {
371*d83cc019SAndroid Build Coastguard Worker char *wc;
372*d83cc019SAndroid Build Coastguard Worker
373*d83cc019SAndroid Build Coastguard Worker if (before == I915_GEM_DOMAIN_CPU)
374*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__cpu(fd, obj.handle, 0, OBJSZ, PROT_WRITE);
375*d83cc019SAndroid Build Coastguard Worker else if (before == I915_GEM_DOMAIN_GTT)
376*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__gtt(fd, obj.handle, OBJSZ, PROT_WRITE);
377*d83cc019SAndroid Build Coastguard Worker else if (before == I915_GEM_DOMAIN_WC)
378*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__wc(fd, obj.handle, 0, OBJSZ, PROT_WRITE);
379*d83cc019SAndroid Build Coastguard Worker else
380*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
381*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj.handle, before, before);
382*d83cc019SAndroid Build Coastguard Worker offset = -1;
383*d83cc019SAndroid Build Coastguard Worker memcpy(wc + reloc_offset, &offset, sizeof(offset));
384*d83cc019SAndroid Build Coastguard Worker munmap(wc, OBJSZ);
385*d83cc019SAndroid Build Coastguard Worker } else {
386*d83cc019SAndroid Build Coastguard Worker offset = -1;
387*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj.handle, reloc_offset, &offset, sizeof(offset));
388*d83cc019SAndroid Build Coastguard Worker }
389*d83cc019SAndroid Build Coastguard Worker
390*d83cc019SAndroid Build Coastguard Worker if (flags & ACTIVE) {
391*d83cc019SAndroid Build Coastguard Worker spin = igt_spin_new(fd,
392*d83cc019SAndroid Build Coastguard Worker .engine = I915_EXEC_DEFAULT,
393*d83cc019SAndroid Build Coastguard Worker .dependency = obj.handle);
394*d83cc019SAndroid Build Coastguard Worker if (!(flags & HANG))
395*d83cc019SAndroid Build Coastguard Worker igt_spin_set_timeout(spin, NSEC_PER_SEC/100);
396*d83cc019SAndroid Build Coastguard Worker igt_assert(gem_bo_busy(fd, obj.handle));
397*d83cc019SAndroid Build Coastguard Worker }
398*d83cc019SAndroid Build Coastguard Worker
399*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
400*d83cc019SAndroid Build Coastguard Worker
401*d83cc019SAndroid Build Coastguard Worker if (after) {
402*d83cc019SAndroid Build Coastguard Worker char *wc;
403*d83cc019SAndroid Build Coastguard Worker
404*d83cc019SAndroid Build Coastguard Worker if (after == I915_GEM_DOMAIN_CPU)
405*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__cpu(fd, obj.handle, 0, OBJSZ, PROT_READ);
406*d83cc019SAndroid Build Coastguard Worker else if (after == I915_GEM_DOMAIN_GTT)
407*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__gtt(fd, obj.handle, OBJSZ, PROT_READ);
408*d83cc019SAndroid Build Coastguard Worker else if (after == I915_GEM_DOMAIN_WC)
409*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__wc(fd, obj.handle, 0, OBJSZ, PROT_READ);
410*d83cc019SAndroid Build Coastguard Worker else
411*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
412*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj.handle, after, 0);
413*d83cc019SAndroid Build Coastguard Worker offset = ~reloc.presumed_offset & address_mask;
414*d83cc019SAndroid Build Coastguard Worker memcpy(&offset, wc + reloc_offset, has_64b_reloc(fd) ? 8 : 4);
415*d83cc019SAndroid Build Coastguard Worker munmap(wc, OBJSZ);
416*d83cc019SAndroid Build Coastguard Worker } else {
417*d83cc019SAndroid Build Coastguard Worker offset = ~reloc.presumed_offset & address_mask;
418*d83cc019SAndroid Build Coastguard Worker gem_read(fd, obj.handle, reloc_offset, &offset, has_64b_reloc(fd) ? 8 : 4);
419*d83cc019SAndroid Build Coastguard Worker }
420*d83cc019SAndroid Build Coastguard Worker
421*d83cc019SAndroid Build Coastguard Worker if (reloc.presumed_offset == -1)
422*d83cc019SAndroid Build Coastguard Worker igt_warn("reloc.presumed_offset == -1\n");
423*d83cc019SAndroid Build Coastguard Worker else
424*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(reloc.presumed_offset, offset);
425*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(obj.offset, offset);
426*d83cc019SAndroid Build Coastguard Worker
427*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin);
428*d83cc019SAndroid Build Coastguard Worker
429*d83cc019SAndroid Build Coastguard Worker /* Simulate relocation */
430*d83cc019SAndroid Build Coastguard Worker if (flags & NORELOC) {
431*d83cc019SAndroid Build Coastguard Worker obj.offset += OBJSZ;
432*d83cc019SAndroid Build Coastguard Worker reloc.presumed_offset += OBJSZ;
433*d83cc019SAndroid Build Coastguard Worker } else {
434*d83cc019SAndroid Build Coastguard Worker trash = obj.handle;
435*d83cc019SAndroid Build Coastguard Worker obj.handle = gem_create(fd, OBJSZ);
436*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj.handle, 0, &bbe, sizeof(bbe));
437*d83cc019SAndroid Build Coastguard Worker reloc.target_handle = obj.handle;
438*d83cc019SAndroid Build Coastguard Worker }
439*d83cc019SAndroid Build Coastguard Worker
440*d83cc019SAndroid Build Coastguard Worker if (before) {
441*d83cc019SAndroid Build Coastguard Worker char *wc;
442*d83cc019SAndroid Build Coastguard Worker
443*d83cc019SAndroid Build Coastguard Worker if (before == I915_GEM_DOMAIN_CPU)
444*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__cpu(fd, obj.handle, 0, OBJSZ, PROT_WRITE);
445*d83cc019SAndroid Build Coastguard Worker else if (before == I915_GEM_DOMAIN_GTT)
446*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__gtt(fd, obj.handle, OBJSZ, PROT_WRITE);
447*d83cc019SAndroid Build Coastguard Worker else if (before == I915_GEM_DOMAIN_WC)
448*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__wc(fd, obj.handle, 0, OBJSZ, PROT_WRITE);
449*d83cc019SAndroid Build Coastguard Worker else
450*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
451*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj.handle, before, before);
452*d83cc019SAndroid Build Coastguard Worker memcpy(wc + reloc_offset, &reloc.presumed_offset, sizeof(reloc.presumed_offset));
453*d83cc019SAndroid Build Coastguard Worker munmap(wc, OBJSZ);
454*d83cc019SAndroid Build Coastguard Worker } else {
455*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj.handle, reloc_offset, &reloc.presumed_offset, sizeof(reloc.presumed_offset));
456*d83cc019SAndroid Build Coastguard Worker }
457*d83cc019SAndroid Build Coastguard Worker
458*d83cc019SAndroid Build Coastguard Worker if (flags & ACTIVE) {
459*d83cc019SAndroid Build Coastguard Worker spin = igt_spin_new(fd,
460*d83cc019SAndroid Build Coastguard Worker .engine = I915_EXEC_DEFAULT,
461*d83cc019SAndroid Build Coastguard Worker .dependency = obj.handle);
462*d83cc019SAndroid Build Coastguard Worker if (!(flags & HANG))
463*d83cc019SAndroid Build Coastguard Worker igt_spin_set_timeout(spin, NSEC_PER_SEC/100);
464*d83cc019SAndroid Build Coastguard Worker igt_assert(gem_bo_busy(fd, obj.handle));
465*d83cc019SAndroid Build Coastguard Worker }
466*d83cc019SAndroid Build Coastguard Worker
467*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
468*d83cc019SAndroid Build Coastguard Worker
469*d83cc019SAndroid Build Coastguard Worker if (after) {
470*d83cc019SAndroid Build Coastguard Worker char *wc;
471*d83cc019SAndroid Build Coastguard Worker
472*d83cc019SAndroid Build Coastguard Worker if (after == I915_GEM_DOMAIN_CPU)
473*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__cpu(fd, obj.handle, 0, OBJSZ, PROT_READ);
474*d83cc019SAndroid Build Coastguard Worker else if (after == I915_GEM_DOMAIN_GTT)
475*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__gtt(fd, obj.handle, OBJSZ, PROT_READ);
476*d83cc019SAndroid Build Coastguard Worker else if (after == I915_GEM_DOMAIN_WC)
477*d83cc019SAndroid Build Coastguard Worker wc = gem_mmap__wc(fd, obj.handle, 0, OBJSZ, PROT_READ);
478*d83cc019SAndroid Build Coastguard Worker else
479*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
480*d83cc019SAndroid Build Coastguard Worker gem_set_domain(fd, obj.handle, after, 0);
481*d83cc019SAndroid Build Coastguard Worker offset = ~reloc.presumed_offset & address_mask;
482*d83cc019SAndroid Build Coastguard Worker memcpy(&offset, wc + reloc_offset, has_64b_reloc(fd) ? 8 : 4);
483*d83cc019SAndroid Build Coastguard Worker munmap(wc, OBJSZ);
484*d83cc019SAndroid Build Coastguard Worker } else {
485*d83cc019SAndroid Build Coastguard Worker offset = ~reloc.presumed_offset & address_mask;
486*d83cc019SAndroid Build Coastguard Worker gem_read(fd, obj.handle, reloc_offset, &offset, has_64b_reloc(fd) ? 8 : 4);
487*d83cc019SAndroid Build Coastguard Worker }
488*d83cc019SAndroid Build Coastguard Worker
489*d83cc019SAndroid Build Coastguard Worker if (reloc.presumed_offset == -1)
490*d83cc019SAndroid Build Coastguard Worker igt_warn("reloc.presumed_offset == -1\n");
491*d83cc019SAndroid Build Coastguard Worker else
492*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(reloc.presumed_offset, offset);
493*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(obj.offset, offset);
494*d83cc019SAndroid Build Coastguard Worker
495*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin);
496*d83cc019SAndroid Build Coastguard Worker if (trash)
497*d83cc019SAndroid Build Coastguard Worker gem_close(fd, trash);
498*d83cc019SAndroid Build Coastguard Worker }
499*d83cc019SAndroid Build Coastguard Worker
500*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj.handle);
501*d83cc019SAndroid Build Coastguard Worker }
502*d83cc019SAndroid Build Coastguard Worker
sign_extend(uint64_t x,int index)503*d83cc019SAndroid Build Coastguard Worker static inline uint64_t sign_extend(uint64_t x, int index)
504*d83cc019SAndroid Build Coastguard Worker {
505*d83cc019SAndroid Build Coastguard Worker int shift = 63 - index;
506*d83cc019SAndroid Build Coastguard Worker return (int64_t)(x << shift) >> shift;
507*d83cc019SAndroid Build Coastguard Worker }
508*d83cc019SAndroid Build Coastguard Worker
gen8_canonical_address(uint64_t address)509*d83cc019SAndroid Build Coastguard Worker static uint64_t gen8_canonical_address(uint64_t address)
510*d83cc019SAndroid Build Coastguard Worker {
511*d83cc019SAndroid Build Coastguard Worker return sign_extend(address, 47);
512*d83cc019SAndroid Build Coastguard Worker }
513*d83cc019SAndroid Build Coastguard Worker
basic_range(int fd,unsigned flags)514*d83cc019SAndroid Build Coastguard Worker static void basic_range(int fd, unsigned flags)
515*d83cc019SAndroid Build Coastguard Worker {
516*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_relocation_entry reloc[128];
517*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj[128];
518*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
519*d83cc019SAndroid Build Coastguard Worker uint64_t address_mask = has_64b_reloc(fd) ? ~(uint64_t)0 : ~(uint32_t)0;
520*d83cc019SAndroid Build Coastguard Worker uint64_t gtt_size = gem_aperture_size(fd);
521*d83cc019SAndroid Build Coastguard Worker const uint32_t bbe = MI_BATCH_BUFFER_END;
522*d83cc019SAndroid Build Coastguard Worker igt_spin_t *spin = NULL;
523*d83cc019SAndroid Build Coastguard Worker int count, n;
524*d83cc019SAndroid Build Coastguard Worker
525*d83cc019SAndroid Build Coastguard Worker igt_require(gem_has_softpin(fd));
526*d83cc019SAndroid Build Coastguard Worker
527*d83cc019SAndroid Build Coastguard Worker for (count = 12; gtt_size >> (count + 1); count++)
528*d83cc019SAndroid Build Coastguard Worker ;
529*d83cc019SAndroid Build Coastguard Worker
530*d83cc019SAndroid Build Coastguard Worker count -= 12;
531*d83cc019SAndroid Build Coastguard Worker
532*d83cc019SAndroid Build Coastguard Worker memset(obj, 0, sizeof(obj));
533*d83cc019SAndroid Build Coastguard Worker memset(reloc, 0, sizeof(reloc));
534*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
535*d83cc019SAndroid Build Coastguard Worker
536*d83cc019SAndroid Build Coastguard Worker n = 0;
537*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i <= count; i++) {
538*d83cc019SAndroid Build Coastguard Worker obj[n].handle = gem_create(fd, 4096);
539*d83cc019SAndroid Build Coastguard Worker obj[n].offset = (1ull << (i + 12)) - 4096;
540*d83cc019SAndroid Build Coastguard Worker obj[n].offset = gen8_canonical_address(obj[n].offset);
541*d83cc019SAndroid Build Coastguard Worker obj[n].flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
542*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[n].handle, 0, &bbe, sizeof(bbe));
543*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&obj[n]);
544*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
545*d83cc019SAndroid Build Coastguard Worker if (__gem_execbuf(fd, &execbuf))
546*d83cc019SAndroid Build Coastguard Worker continue;
547*d83cc019SAndroid Build Coastguard Worker
548*d83cc019SAndroid Build Coastguard Worker igt_debug("obj[%d] handle=%d, address=%llx\n",
549*d83cc019SAndroid Build Coastguard Worker n, obj[n].handle, (long long)obj[n].offset);
550*d83cc019SAndroid Build Coastguard Worker
551*d83cc019SAndroid Build Coastguard Worker reloc[n].offset = 8 * (n + 1);
552*d83cc019SAndroid Build Coastguard Worker reloc[n].target_handle = obj[n].handle;
553*d83cc019SAndroid Build Coastguard Worker reloc[n].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
554*d83cc019SAndroid Build Coastguard Worker reloc[n].presumed_offset = -1;
555*d83cc019SAndroid Build Coastguard Worker n++;
556*d83cc019SAndroid Build Coastguard Worker }
557*d83cc019SAndroid Build Coastguard Worker for (int i = 1; i < count; i++) {
558*d83cc019SAndroid Build Coastguard Worker obj[n].handle = gem_create(fd, 4096);
559*d83cc019SAndroid Build Coastguard Worker obj[n].offset = 1ull << (i + 12);
560*d83cc019SAndroid Build Coastguard Worker obj[n].offset = gen8_canonical_address(obj[n].offset);
561*d83cc019SAndroid Build Coastguard Worker obj[n].flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS;
562*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[n].handle, 0, &bbe, sizeof(bbe));
563*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&obj[n]);
564*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
565*d83cc019SAndroid Build Coastguard Worker if (__gem_execbuf(fd, &execbuf))
566*d83cc019SAndroid Build Coastguard Worker continue;
567*d83cc019SAndroid Build Coastguard Worker
568*d83cc019SAndroid Build Coastguard Worker igt_debug("obj[%d] handle=%d, address=%llx\n",
569*d83cc019SAndroid Build Coastguard Worker n, obj[n].handle, (long long)obj[n].offset);
570*d83cc019SAndroid Build Coastguard Worker
571*d83cc019SAndroid Build Coastguard Worker reloc[n].offset = 8 * (n + 1);
572*d83cc019SAndroid Build Coastguard Worker reloc[n].target_handle = obj[n].handle;
573*d83cc019SAndroid Build Coastguard Worker reloc[n].read_domains = I915_GEM_DOMAIN_INSTRUCTION;
574*d83cc019SAndroid Build Coastguard Worker reloc[n].presumed_offset = -1;
575*d83cc019SAndroid Build Coastguard Worker n++;
576*d83cc019SAndroid Build Coastguard Worker }
577*d83cc019SAndroid Build Coastguard Worker igt_require(n);
578*d83cc019SAndroid Build Coastguard Worker
579*d83cc019SAndroid Build Coastguard Worker obj[n].handle = gem_create(fd, 4096);
580*d83cc019SAndroid Build Coastguard Worker obj[n].relocs_ptr = to_user_pointer(reloc);
581*d83cc019SAndroid Build Coastguard Worker obj[n].relocation_count = n;
582*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[n].handle, 0, &bbe, sizeof(bbe));
583*d83cc019SAndroid Build Coastguard Worker
584*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(obj);
585*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = n + 1;
586*d83cc019SAndroid Build Coastguard Worker
587*d83cc019SAndroid Build Coastguard Worker if (flags & ACTIVE) {
588*d83cc019SAndroid Build Coastguard Worker spin = igt_spin_new(fd, .dependency = obj[n].handle);
589*d83cc019SAndroid Build Coastguard Worker if (!(flags & HANG))
590*d83cc019SAndroid Build Coastguard Worker igt_spin_set_timeout(spin, NSEC_PER_SEC/100);
591*d83cc019SAndroid Build Coastguard Worker igt_assert(gem_bo_busy(fd, obj[n].handle));
592*d83cc019SAndroid Build Coastguard Worker }
593*d83cc019SAndroid Build Coastguard Worker
594*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
595*d83cc019SAndroid Build Coastguard Worker igt_spin_free(fd, spin);
596*d83cc019SAndroid Build Coastguard Worker
597*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i < n; i++) {
598*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
599*d83cc019SAndroid Build Coastguard Worker
600*d83cc019SAndroid Build Coastguard Worker offset = ~reloc[i].presumed_offset & address_mask;
601*d83cc019SAndroid Build Coastguard Worker gem_read(fd, obj[n].handle, reloc[i].offset,
602*d83cc019SAndroid Build Coastguard Worker &offset, has_64b_reloc(fd) ? 8 : 4);
603*d83cc019SAndroid Build Coastguard Worker
604*d83cc019SAndroid Build Coastguard Worker igt_debug("obj[%d] handle=%d, offset=%llx, found=%llx, presumed=%llx\n",
605*d83cc019SAndroid Build Coastguard Worker i, obj[i].handle,
606*d83cc019SAndroid Build Coastguard Worker (long long)obj[i].offset,
607*d83cc019SAndroid Build Coastguard Worker (long long)offset,
608*d83cc019SAndroid Build Coastguard Worker (long long)reloc[i].presumed_offset);
609*d83cc019SAndroid Build Coastguard Worker
610*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(obj[i].offset, offset);
611*d83cc019SAndroid Build Coastguard Worker if (reloc[i].presumed_offset == -1)
612*d83cc019SAndroid Build Coastguard Worker igt_warn("reloc.presumed_offset == -1\n");
613*d83cc019SAndroid Build Coastguard Worker else
614*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(reloc[i].presumed_offset, offset);
615*d83cc019SAndroid Build Coastguard Worker }
616*d83cc019SAndroid Build Coastguard Worker
617*d83cc019SAndroid Build Coastguard Worker for (int i = 0; i <= n; i++)
618*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[i].handle);
619*d83cc019SAndroid Build Coastguard Worker }
620*d83cc019SAndroid Build Coastguard Worker
basic_softpin(int fd)621*d83cc019SAndroid Build Coastguard Worker static void basic_softpin(int fd)
622*d83cc019SAndroid Build Coastguard Worker {
623*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_exec_object2 obj[2];
624*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_execbuffer2 execbuf;
625*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
626*d83cc019SAndroid Build Coastguard Worker uint32_t bbe = MI_BATCH_BUFFER_END;
627*d83cc019SAndroid Build Coastguard Worker
628*d83cc019SAndroid Build Coastguard Worker igt_require(gem_has_softpin(fd));
629*d83cc019SAndroid Build Coastguard Worker
630*d83cc019SAndroid Build Coastguard Worker memset(obj, 0, sizeof(obj));
631*d83cc019SAndroid Build Coastguard Worker obj[1].handle = gem_create(fd, 4096);
632*d83cc019SAndroid Build Coastguard Worker gem_write(fd, obj[1].handle, 0, &bbe, sizeof(bbe));
633*d83cc019SAndroid Build Coastguard Worker
634*d83cc019SAndroid Build Coastguard Worker memset(&execbuf, 0, sizeof(execbuf));
635*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&obj[1]);
636*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 1;
637*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
638*d83cc019SAndroid Build Coastguard Worker
639*d83cc019SAndroid Build Coastguard Worker offset = obj[1].offset;
640*d83cc019SAndroid Build Coastguard Worker
641*d83cc019SAndroid Build Coastguard Worker obj[0].handle = gem_create(fd, 4096);
642*d83cc019SAndroid Build Coastguard Worker obj[0].offset = obj[1].offset;
643*d83cc019SAndroid Build Coastguard Worker obj[0].flags = EXEC_OBJECT_PINNED;
644*d83cc019SAndroid Build Coastguard Worker
645*d83cc019SAndroid Build Coastguard Worker execbuf.buffers_ptr = to_user_pointer(&obj[0]);
646*d83cc019SAndroid Build Coastguard Worker execbuf.buffer_count = 2;
647*d83cc019SAndroid Build Coastguard Worker
648*d83cc019SAndroid Build Coastguard Worker gem_execbuf(fd, &execbuf);
649*d83cc019SAndroid Build Coastguard Worker igt_assert_eq_u64(obj[0].offset, offset);
650*d83cc019SAndroid Build Coastguard Worker
651*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[0].handle);
652*d83cc019SAndroid Build Coastguard Worker gem_close(fd, obj[1].handle);
653*d83cc019SAndroid Build Coastguard Worker }
654*d83cc019SAndroid Build Coastguard Worker
655*d83cc019SAndroid Build Coastguard Worker igt_main
656*d83cc019SAndroid Build Coastguard Worker {
657*d83cc019SAndroid Build Coastguard Worker const struct mode {
658*d83cc019SAndroid Build Coastguard Worker const char *name;
659*d83cc019SAndroid Build Coastguard Worker unsigned before, after;
660*d83cc019SAndroid Build Coastguard Worker } modes[] = {
661*d83cc019SAndroid Build Coastguard Worker { "cpu", I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU },
662*d83cc019SAndroid Build Coastguard Worker { "gtt", I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT },
663*d83cc019SAndroid Build Coastguard Worker { "wc", I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_WC },
664*d83cc019SAndroid Build Coastguard Worker { "cpu-gtt", I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_GTT },
665*d83cc019SAndroid Build Coastguard Worker { "gtt-cpu", I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_CPU },
666*d83cc019SAndroid Build Coastguard Worker { "cpu-wc", I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_WC },
667*d83cc019SAndroid Build Coastguard Worker { "wc-cpu", I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_CPU },
668*d83cc019SAndroid Build Coastguard Worker { "gtt-wc", I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_WC },
669*d83cc019SAndroid Build Coastguard Worker { "wc-gtt", I915_GEM_DOMAIN_WC, I915_GEM_DOMAIN_GTT },
670*d83cc019SAndroid Build Coastguard Worker { "cpu-read", I915_GEM_DOMAIN_CPU, 0 },
671*d83cc019SAndroid Build Coastguard Worker { "gtt-read", I915_GEM_DOMAIN_GTT, 0 },
672*d83cc019SAndroid Build Coastguard Worker { "wc-read", I915_GEM_DOMAIN_WC, 0 },
673*d83cc019SAndroid Build Coastguard Worker { "write-cpu", 0, I915_GEM_DOMAIN_CPU },
674*d83cc019SAndroid Build Coastguard Worker { "write-gtt", 0, I915_GEM_DOMAIN_GTT },
675*d83cc019SAndroid Build Coastguard Worker { "write-wc", 0, I915_GEM_DOMAIN_WC },
676*d83cc019SAndroid Build Coastguard Worker { "write-read", 0, 0 },
677*d83cc019SAndroid Build Coastguard Worker { },
678*d83cc019SAndroid Build Coastguard Worker }, *m;
679*d83cc019SAndroid Build Coastguard Worker const struct flags {
680*d83cc019SAndroid Build Coastguard Worker const char *name;
681*d83cc019SAndroid Build Coastguard Worker unsigned flags;
682*d83cc019SAndroid Build Coastguard Worker bool basic;
683*d83cc019SAndroid Build Coastguard Worker } flags[] = {
684*d83cc019SAndroid Build Coastguard Worker { "", 0 , true},
685*d83cc019SAndroid Build Coastguard Worker { "-noreloc", NORELOC, true },
686*d83cc019SAndroid Build Coastguard Worker { "-active", ACTIVE, true },
687*d83cc019SAndroid Build Coastguard Worker { "-hang", ACTIVE | HANG },
688*d83cc019SAndroid Build Coastguard Worker { },
689*d83cc019SAndroid Build Coastguard Worker }, *f;
690*d83cc019SAndroid Build Coastguard Worker uint64_t size;
691*d83cc019SAndroid Build Coastguard Worker int fd = -1;
692*d83cc019SAndroid Build Coastguard Worker
693*d83cc019SAndroid Build Coastguard Worker igt_fixture {
694*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver_master(DRIVER_INTEL);
695*d83cc019SAndroid Build Coastguard Worker igt_require_gem(fd);
696*d83cc019SAndroid Build Coastguard Worker }
697*d83cc019SAndroid Build Coastguard Worker
698*d83cc019SAndroid Build Coastguard Worker for (f = flags; f->name; f++) {
699*d83cc019SAndroid Build Coastguard Worker igt_hang_t hang;
700*d83cc019SAndroid Build Coastguard Worker
701*d83cc019SAndroid Build Coastguard Worker igt_subtest_group {
702*d83cc019SAndroid Build Coastguard Worker igt_fixture {
703*d83cc019SAndroid Build Coastguard Worker if (f->flags & HANG)
704*d83cc019SAndroid Build Coastguard Worker hang = igt_allow_hang(fd, 0, 0);
705*d83cc019SAndroid Build Coastguard Worker }
706*d83cc019SAndroid Build Coastguard Worker
707*d83cc019SAndroid Build Coastguard Worker for (m = modes; m->name; m++) {
708*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%s%s%s",
709*d83cc019SAndroid Build Coastguard Worker f->basic ? "basic-" : "",
710*d83cc019SAndroid Build Coastguard Worker m->name,
711*d83cc019SAndroid Build Coastguard Worker f->name) {
712*d83cc019SAndroid Build Coastguard Worker if ((m->before | m->after) & I915_GEM_DOMAIN_WC)
713*d83cc019SAndroid Build Coastguard Worker igt_require(gem_mmap__has_wc(fd));
714*d83cc019SAndroid Build Coastguard Worker basic_reloc(fd, m->before, m->after, f->flags);
715*d83cc019SAndroid Build Coastguard Worker }
716*d83cc019SAndroid Build Coastguard Worker }
717*d83cc019SAndroid Build Coastguard Worker
718*d83cc019SAndroid Build Coastguard Worker if (!(f->flags & NORELOC)) {
719*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("%srange%s",
720*d83cc019SAndroid Build Coastguard Worker f->basic ? "basic-" : "", f->name)
721*d83cc019SAndroid Build Coastguard Worker basic_range(fd, f->flags);
722*d83cc019SAndroid Build Coastguard Worker }
723*d83cc019SAndroid Build Coastguard Worker
724*d83cc019SAndroid Build Coastguard Worker igt_fixture {
725*d83cc019SAndroid Build Coastguard Worker if (f->flags & HANG)
726*d83cc019SAndroid Build Coastguard Worker igt_disallow_hang(fd, hang);
727*d83cc019SAndroid Build Coastguard Worker }
728*d83cc019SAndroid Build Coastguard Worker }
729*d83cc019SAndroid Build Coastguard Worker }
730*d83cc019SAndroid Build Coastguard Worker
731*d83cc019SAndroid Build Coastguard Worker igt_subtest("basic-softpin")
732*d83cc019SAndroid Build Coastguard Worker basic_softpin(fd);
733*d83cc019SAndroid Build Coastguard Worker
734*d83cc019SAndroid Build Coastguard Worker for (size = 4096; size <= 4ull*1024*1024*1024; size <<= 1) {
735*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("mmap-%u", find_last_set(size) - 1)
736*d83cc019SAndroid Build Coastguard Worker from_mmap(fd, size, MEM);
737*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("readonly-%u", find_last_set(size) - 1)
738*d83cc019SAndroid Build Coastguard Worker from_mmap(fd, size, MEM | RO);
739*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("cpu-%u", find_last_set(size) - 1)
740*d83cc019SAndroid Build Coastguard Worker from_mmap(fd, size, CPU);
find_last_set(size)741*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("wc-%u", find_last_set(size) - 1) {
742*d83cc019SAndroid Build Coastguard Worker igt_require(gem_mmap__has_wc(fd));
743*d83cc019SAndroid Build Coastguard Worker from_mmap(fd, size, WC);
744*d83cc019SAndroid Build Coastguard Worker }
745*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("gtt-%u", find_last_set(size) - 1)
746*d83cc019SAndroid Build Coastguard Worker from_mmap(fd, size, GTT);
747*d83cc019SAndroid Build Coastguard Worker }
748*d83cc019SAndroid Build Coastguard Worker
749*d83cc019SAndroid Build Coastguard Worker igt_subtest("gpu")
750*d83cc019SAndroid Build Coastguard Worker from_gpu(fd);
751*d83cc019SAndroid Build Coastguard Worker
752*d83cc019SAndroid Build Coastguard Worker igt_subtest("active")
753*d83cc019SAndroid Build Coastguard Worker active(fd, ALL_ENGINES);
754*d83cc019SAndroid Build Coastguard Worker for (const struct intel_execution_engine *e = intel_execution_engines;
755*d83cc019SAndroid Build Coastguard Worker e->name; e++) {
756*d83cc019SAndroid Build Coastguard Worker igt_subtest_f("active-%s", e->name)
757*d83cc019SAndroid Build Coastguard Worker active(fd, e->exec_id | e->flags);
758*d83cc019SAndroid Build Coastguard Worker }
759*d83cc019SAndroid Build Coastguard Worker igt_fixture
760*d83cc019SAndroid Build Coastguard Worker close(fd);
761*d83cc019SAndroid Build Coastguard Worker }
762