1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2017-2018 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 * Authors:
24*d83cc019SAndroid Build Coastguard Worker * Lionel Landwerlin <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker *
26*d83cc019SAndroid Build Coastguard Worker */
27*d83cc019SAndroid Build Coastguard Worker
28*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
29*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
33*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
34*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
35*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
36*d83cc019SAndroid Build Coastguard Worker #include <time.h>
37*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
38*d83cc019SAndroid Build Coastguard Worker #include <sys/wait.h>
39*d83cc019SAndroid Build Coastguard Worker
40*d83cc019SAndroid Build Coastguard Worker #include "igt_dummyload.h"
41*d83cc019SAndroid Build Coastguard Worker #include "igt_perf.h"
42*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
43*d83cc019SAndroid Build Coastguard Worker #include "ioctl_wrappers.h"
44*d83cc019SAndroid Build Coastguard Worker
45*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Test context render powergating programming.");
46*d83cc019SAndroid Build Coastguard Worker
47*d83cc019SAndroid Build Coastguard Worker static unsigned int __intel_gen__, __intel_devid__;
48*d83cc019SAndroid Build Coastguard Worker static uint64_t __slice_mask__, __subslice_mask__;
49*d83cc019SAndroid Build Coastguard Worker static unsigned int __slice_count__, __subslice_count__;
50*d83cc019SAndroid Build Coastguard Worker
mask_minus_one(uint64_t mask)51*d83cc019SAndroid Build Coastguard Worker static uint64_t mask_minus_one(uint64_t mask)
52*d83cc019SAndroid Build Coastguard Worker {
53*d83cc019SAndroid Build Coastguard Worker unsigned int i;
54*d83cc019SAndroid Build Coastguard Worker
55*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < (sizeof(mask) * 8 - 1); i++) {
56*d83cc019SAndroid Build Coastguard Worker if ((1ULL << i) & mask)
57*d83cc019SAndroid Build Coastguard Worker return mask & ~(1ULL << i);
58*d83cc019SAndroid Build Coastguard Worker }
59*d83cc019SAndroid Build Coastguard Worker
60*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
61*d83cc019SAndroid Build Coastguard Worker return 0;
62*d83cc019SAndroid Build Coastguard Worker }
63*d83cc019SAndroid Build Coastguard Worker
mask_plus_one(uint64_t mask)64*d83cc019SAndroid Build Coastguard Worker static uint64_t mask_plus_one(uint64_t mask)
65*d83cc019SAndroid Build Coastguard Worker {
66*d83cc019SAndroid Build Coastguard Worker unsigned int i;
67*d83cc019SAndroid Build Coastguard Worker
68*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < (sizeof(mask) * 8 - 1); i++) {
69*d83cc019SAndroid Build Coastguard Worker if (((1ULL << i) & mask) == 0)
70*d83cc019SAndroid Build Coastguard Worker return mask | (1ULL << i);
71*d83cc019SAndroid Build Coastguard Worker }
72*d83cc019SAndroid Build Coastguard Worker
73*d83cc019SAndroid Build Coastguard Worker igt_assert(0);
74*d83cc019SAndroid Build Coastguard Worker return 0;
75*d83cc019SAndroid Build Coastguard Worker }
76*d83cc019SAndroid Build Coastguard Worker
mask_minus(uint64_t mask,int n)77*d83cc019SAndroid Build Coastguard Worker static uint64_t mask_minus(uint64_t mask, int n)
78*d83cc019SAndroid Build Coastguard Worker {
79*d83cc019SAndroid Build Coastguard Worker unsigned int i;
80*d83cc019SAndroid Build Coastguard Worker
81*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < n; i++)
82*d83cc019SAndroid Build Coastguard Worker mask = mask_minus_one(mask);
83*d83cc019SAndroid Build Coastguard Worker
84*d83cc019SAndroid Build Coastguard Worker return mask;
85*d83cc019SAndroid Build Coastguard Worker }
86*d83cc019SAndroid Build Coastguard Worker
mask_plus(uint64_t mask,int n)87*d83cc019SAndroid Build Coastguard Worker static uint64_t mask_plus(uint64_t mask, int n)
88*d83cc019SAndroid Build Coastguard Worker {
89*d83cc019SAndroid Build Coastguard Worker unsigned int i;
90*d83cc019SAndroid Build Coastguard Worker
91*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < n; i++)
92*d83cc019SAndroid Build Coastguard Worker mask = mask_plus_one(mask);
93*d83cc019SAndroid Build Coastguard Worker
94*d83cc019SAndroid Build Coastguard Worker return mask;
95*d83cc019SAndroid Build Coastguard Worker }
96*d83cc019SAndroid Build Coastguard Worker
97*d83cc019SAndroid Build Coastguard Worker static bool
kernel_has_per_context_sseu_support(int fd)98*d83cc019SAndroid Build Coastguard Worker kernel_has_per_context_sseu_support(int fd)
99*d83cc019SAndroid Build Coastguard Worker {
100*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param_sseu sseu = { };
101*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param arg = {
102*d83cc019SAndroid Build Coastguard Worker .param = I915_CONTEXT_PARAM_SSEU,
103*d83cc019SAndroid Build Coastguard Worker .size = sizeof(sseu),
104*d83cc019SAndroid Build Coastguard Worker .value = to_user_pointer(&sseu),
105*d83cc019SAndroid Build Coastguard Worker };
106*d83cc019SAndroid Build Coastguard Worker int ret;
107*d83cc019SAndroid Build Coastguard Worker
108*d83cc019SAndroid Build Coastguard Worker if (__gem_context_get_param(fd, &arg))
109*d83cc019SAndroid Build Coastguard Worker return false;
110*d83cc019SAndroid Build Coastguard Worker
111*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(&sseu);
112*d83cc019SAndroid Build Coastguard Worker
113*d83cc019SAndroid Build Coastguard Worker ret = __gem_context_set_param(fd, &arg);
114*d83cc019SAndroid Build Coastguard Worker
115*d83cc019SAndroid Build Coastguard Worker igt_assert(ret == 0 || ret == -ENODEV || ret == -EINVAL);
116*d83cc019SAndroid Build Coastguard Worker
117*d83cc019SAndroid Build Coastguard Worker return ret == 0;
118*d83cc019SAndroid Build Coastguard Worker }
119*d83cc019SAndroid Build Coastguard Worker
has_engine(int fd,unsigned int class,unsigned int instance)120*d83cc019SAndroid Build Coastguard Worker static bool has_engine(int fd, unsigned int class, unsigned int instance)
121*d83cc019SAndroid Build Coastguard Worker {
122*d83cc019SAndroid Build Coastguard Worker int pmu = perf_i915_open(I915_PMU_ENGINE_BUSY(class, instance));
123*d83cc019SAndroid Build Coastguard Worker
124*d83cc019SAndroid Build Coastguard Worker if (pmu >= 0)
125*d83cc019SAndroid Build Coastguard Worker close(pmu);
126*d83cc019SAndroid Build Coastguard Worker
127*d83cc019SAndroid Build Coastguard Worker return pmu >= 0;
128*d83cc019SAndroid Build Coastguard Worker }
129*d83cc019SAndroid Build Coastguard Worker
130*d83cc019SAndroid Build Coastguard Worker /*
131*d83cc019SAndroid Build Coastguard Worker * Verify that invalid engines are rejected and valid ones are accepted.
132*d83cc019SAndroid Build Coastguard Worker */
test_engines(int fd)133*d83cc019SAndroid Build Coastguard Worker static void test_engines(int fd)
134*d83cc019SAndroid Build Coastguard Worker {
135*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param_sseu sseu = { };
136*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param arg = {
137*d83cc019SAndroid Build Coastguard Worker .param = I915_CONTEXT_PARAM_SSEU,
138*d83cc019SAndroid Build Coastguard Worker .ctx_id = gem_context_create(fd),
139*d83cc019SAndroid Build Coastguard Worker .size = sizeof(sseu),
140*d83cc019SAndroid Build Coastguard Worker .value = to_user_pointer(&sseu)
141*d83cc019SAndroid Build Coastguard Worker };
142*d83cc019SAndroid Build Coastguard Worker unsigned int class, instance;
143*d83cc019SAndroid Build Coastguard Worker int last_with_engines;
144*d83cc019SAndroid Build Coastguard Worker
145*d83cc019SAndroid Build Coastguard Worker /* get_param */
146*d83cc019SAndroid Build Coastguard Worker
147*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_instance = -1; /* Assumed invalid. */
148*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EINVAL);
149*d83cc019SAndroid Build Coastguard Worker
150*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_class = I915_ENGINE_CLASS_INVALID; /* Both invalid. */
151*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EINVAL);
152*d83cc019SAndroid Build Coastguard Worker
153*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_instance = 0; /* Class invalid. */
154*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EINVAL);
155*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_class = I915_ENGINE_CLASS_RENDER;
156*d83cc019SAndroid Build Coastguard Worker
157*d83cc019SAndroid Build Coastguard Worker last_with_engines = -1;
158*d83cc019SAndroid Build Coastguard Worker for (class = 0; class < ~0; class++) {
159*d83cc019SAndroid Build Coastguard Worker for (instance = 0; instance < ~0; instance++) {
160*d83cc019SAndroid Build Coastguard Worker int ret;
161*d83cc019SAndroid Build Coastguard Worker
162*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_class = class;
163*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_instance = instance;
164*d83cc019SAndroid Build Coastguard Worker
165*d83cc019SAndroid Build Coastguard Worker ret = __gem_context_get_param(fd, &arg);
166*d83cc019SAndroid Build Coastguard Worker
167*d83cc019SAndroid Build Coastguard Worker if (has_engine(fd, class, instance)) {
168*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, 0);
169*d83cc019SAndroid Build Coastguard Worker last_with_engines = class;
170*d83cc019SAndroid Build Coastguard Worker } else {
171*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, -EINVAL);
172*d83cc019SAndroid Build Coastguard Worker if (instance > 8) /* Skip over some instance holes. */
173*d83cc019SAndroid Build Coastguard Worker break;
174*d83cc019SAndroid Build Coastguard Worker }
175*d83cc019SAndroid Build Coastguard Worker }
176*d83cc019SAndroid Build Coastguard Worker
177*d83cc019SAndroid Build Coastguard Worker if (class - last_with_engines > 8) /* Skip over some class holes. */
178*d83cc019SAndroid Build Coastguard Worker break;
179*d83cc019SAndroid Build Coastguard Worker }
180*d83cc019SAndroid Build Coastguard Worker
181*d83cc019SAndroid Build Coastguard Worker /*
182*d83cc019SAndroid Build Coastguard Worker * Get some proper values before trying to reprogram them onto
183*d83cc019SAndroid Build Coastguard Worker * an invalid engine.
184*d83cc019SAndroid Build Coastguard Worker */
185*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_class = 0;
186*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_instance = 0;
187*d83cc019SAndroid Build Coastguard Worker gem_context_get_param(fd, &arg);
188*d83cc019SAndroid Build Coastguard Worker
189*d83cc019SAndroid Build Coastguard Worker /* set_param */
190*d83cc019SAndroid Build Coastguard Worker
191*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_instance = -1; /* Assumed invalid. */
192*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
193*d83cc019SAndroid Build Coastguard Worker
194*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_class = I915_ENGINE_CLASS_INVALID; /* Both invalid. */
195*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
196*d83cc019SAndroid Build Coastguard Worker
197*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_instance = 0; /* Class invalid. */
198*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
199*d83cc019SAndroid Build Coastguard Worker
200*d83cc019SAndroid Build Coastguard Worker last_with_engines = -1;
201*d83cc019SAndroid Build Coastguard Worker for (class = 0; class < ~0; class++) {
202*d83cc019SAndroid Build Coastguard Worker for (instance = 0; instance < ~0; instance++) {
203*d83cc019SAndroid Build Coastguard Worker int ret;
204*d83cc019SAndroid Build Coastguard Worker
205*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_class = class;
206*d83cc019SAndroid Build Coastguard Worker sseu.engine.engine_instance = instance;
207*d83cc019SAndroid Build Coastguard Worker
208*d83cc019SAndroid Build Coastguard Worker ret = __gem_context_set_param(fd, &arg);
209*d83cc019SAndroid Build Coastguard Worker
210*d83cc019SAndroid Build Coastguard Worker if (has_engine(fd, class, instance)) {
211*d83cc019SAndroid Build Coastguard Worker igt_assert(ret == 0 || ret == -ENODEV);
212*d83cc019SAndroid Build Coastguard Worker last_with_engines = class;
213*d83cc019SAndroid Build Coastguard Worker } else {
214*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(ret, -EINVAL);
215*d83cc019SAndroid Build Coastguard Worker if (instance > 8) /* Skip over some instance holes. */
216*d83cc019SAndroid Build Coastguard Worker break;
217*d83cc019SAndroid Build Coastguard Worker }
218*d83cc019SAndroid Build Coastguard Worker }
219*d83cc019SAndroid Build Coastguard Worker
220*d83cc019SAndroid Build Coastguard Worker if (class - last_with_engines > 8) /* Skip over some class holes. */
221*d83cc019SAndroid Build Coastguard Worker break;
222*d83cc019SAndroid Build Coastguard Worker }
223*d83cc019SAndroid Build Coastguard Worker
224*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, arg.ctx_id);
225*d83cc019SAndroid Build Coastguard Worker }
226*d83cc019SAndroid Build Coastguard Worker
227*d83cc019SAndroid Build Coastguard Worker /*
228*d83cc019SAndroid Build Coastguard Worker * Verify that invalid arguments are rejected.
229*d83cc019SAndroid Build Coastguard Worker */
230*d83cc019SAndroid Build Coastguard Worker static void
test_invalid_args(int fd)231*d83cc019SAndroid Build Coastguard Worker test_invalid_args(int fd)
232*d83cc019SAndroid Build Coastguard Worker {
233*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param arg = {
234*d83cc019SAndroid Build Coastguard Worker .param = I915_CONTEXT_PARAM_SSEU,
235*d83cc019SAndroid Build Coastguard Worker .ctx_id = gem_context_create(fd),
236*d83cc019SAndroid Build Coastguard Worker };
237*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param_sseu sseu = { };
238*d83cc019SAndroid Build Coastguard Worker unsigned char *page[2];
239*d83cc019SAndroid Build Coastguard Worker unsigned char *addr;
240*d83cc019SAndroid Build Coastguard Worker unsigned int sz;
241*d83cc019SAndroid Build Coastguard Worker
242*d83cc019SAndroid Build Coastguard Worker /* get param */
243*d83cc019SAndroid Build Coastguard Worker
244*d83cc019SAndroid Build Coastguard Worker /* Invalid size. */
245*d83cc019SAndroid Build Coastguard Worker arg.size = 1;
246*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EINVAL);
247*d83cc019SAndroid Build Coastguard Worker
248*d83cc019SAndroid Build Coastguard Worker /* Query size. */
249*d83cc019SAndroid Build Coastguard Worker arg.size = 0;
250*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), 0);
251*d83cc019SAndroid Build Coastguard Worker sz = arg.size;
252*d83cc019SAndroid Build Coastguard Worker
253*d83cc019SAndroid Build Coastguard Worker /* Bad pointers. */
254*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EFAULT);
255*d83cc019SAndroid Build Coastguard Worker arg.value = -1;
256*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EFAULT);
257*d83cc019SAndroid Build Coastguard Worker arg.value = 1;
258*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EFAULT);
259*d83cc019SAndroid Build Coastguard Worker
260*d83cc019SAndroid Build Coastguard Worker /* Unmapped. */
261*d83cc019SAndroid Build Coastguard Worker page[0] = mmap(0, 4096, PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
262*d83cc019SAndroid Build Coastguard Worker igt_assert(page[0] != MAP_FAILED);
263*d83cc019SAndroid Build Coastguard Worker memset(page[0], 0, sizeof(sseu));
264*d83cc019SAndroid Build Coastguard Worker munmap(page[0], 4096);
265*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(page[0]);
266*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EFAULT);
267*d83cc019SAndroid Build Coastguard Worker
268*d83cc019SAndroid Build Coastguard Worker /* Straddle into unmapped area. */
269*d83cc019SAndroid Build Coastguard Worker page[0] = mmap(0, 8192, PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
270*d83cc019SAndroid Build Coastguard Worker igt_assert(page[0] != MAP_FAILED);
271*d83cc019SAndroid Build Coastguard Worker munmap(page[0], 8192);
272*d83cc019SAndroid Build Coastguard Worker page[0] = mmap(page[0], 4096,
273*d83cc019SAndroid Build Coastguard Worker PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
274*d83cc019SAndroid Build Coastguard Worker igt_assert(page[0] != MAP_FAILED);
275*d83cc019SAndroid Build Coastguard Worker memset(page[0], 0, sizeof(sseu));
276*d83cc019SAndroid Build Coastguard Worker page[1] = mmap((void *)((unsigned long)page[0] + 4096), 4096,
277*d83cc019SAndroid Build Coastguard Worker PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
278*d83cc019SAndroid Build Coastguard Worker igt_assert(page[1] != MAP_FAILED);
279*d83cc019SAndroid Build Coastguard Worker memset(page[1], 0, sizeof(sseu));
280*d83cc019SAndroid Build Coastguard Worker munmap(page[1], 4096);
281*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(page[1]) -
282*d83cc019SAndroid Build Coastguard Worker sizeof(struct drm_i915_gem_context_param_sseu) + 4;
283*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EFAULT);
284*d83cc019SAndroid Build Coastguard Worker munmap(page[0], 4096);
285*d83cc019SAndroid Build Coastguard Worker
286*d83cc019SAndroid Build Coastguard Worker /* Straddle into read-only area. */
287*d83cc019SAndroid Build Coastguard Worker page[0] = mmap(0, 8192, PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
288*d83cc019SAndroid Build Coastguard Worker igt_assert(page[0] != MAP_FAILED);
289*d83cc019SAndroid Build Coastguard Worker munmap(page[0], 8192);
290*d83cc019SAndroid Build Coastguard Worker page[0] = mmap(page[0], 4096,
291*d83cc019SAndroid Build Coastguard Worker PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
292*d83cc019SAndroid Build Coastguard Worker igt_assert(page[0] != MAP_FAILED);
293*d83cc019SAndroid Build Coastguard Worker memset(page[0], 0, sizeof(sseu));
294*d83cc019SAndroid Build Coastguard Worker page[1] = mmap((void *)((unsigned long)page[0] + 4096), 4096,
295*d83cc019SAndroid Build Coastguard Worker PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
296*d83cc019SAndroid Build Coastguard Worker igt_assert(page[1] != MAP_FAILED);
297*d83cc019SAndroid Build Coastguard Worker memset(page[1], 0, sizeof(sseu));
298*d83cc019SAndroid Build Coastguard Worker igt_assert(mprotect(page[1], 4096, PROT_READ) == 0);
299*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(page[1] - sizeof(sseu) + 4);
300*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), -EFAULT);
301*d83cc019SAndroid Build Coastguard Worker munmap(page[0], 4096);
302*d83cc019SAndroid Build Coastguard Worker munmap(page[1], 4096);
303*d83cc019SAndroid Build Coastguard Worker
304*d83cc019SAndroid Build Coastguard Worker /* set param */
305*d83cc019SAndroid Build Coastguard Worker
306*d83cc019SAndroid Build Coastguard Worker /* Invalid sizes. */
307*d83cc019SAndroid Build Coastguard Worker arg.size = 1;
308*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
309*d83cc019SAndroid Build Coastguard Worker
310*d83cc019SAndroid Build Coastguard Worker arg.size = 0;
311*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
312*d83cc019SAndroid Build Coastguard Worker arg.size = sz;
313*d83cc019SAndroid Build Coastguard Worker
314*d83cc019SAndroid Build Coastguard Worker /* Bad pointers. */
315*d83cc019SAndroid Build Coastguard Worker arg.value = 0;
316*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EFAULT);
317*d83cc019SAndroid Build Coastguard Worker arg.value = -1;
318*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EFAULT);
319*d83cc019SAndroid Build Coastguard Worker arg.value = 1;
320*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EFAULT);
321*d83cc019SAndroid Build Coastguard Worker
322*d83cc019SAndroid Build Coastguard Worker /* Get valid SSEU. */
323*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(&sseu);
324*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), 0);
325*d83cc019SAndroid Build Coastguard Worker
326*d83cc019SAndroid Build Coastguard Worker /* Invalid MBZ. */
327*d83cc019SAndroid Build Coastguard Worker sseu.flags = -1;
328*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
329*d83cc019SAndroid Build Coastguard Worker sseu.rsvd = -1;
330*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
331*d83cc019SAndroid Build Coastguard Worker sseu.flags = 0;
332*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
333*d83cc019SAndroid Build Coastguard Worker sseu.rsvd = 0;
334*d83cc019SAndroid Build Coastguard Worker
335*d83cc019SAndroid Build Coastguard Worker /* Unmapped. */
336*d83cc019SAndroid Build Coastguard Worker page[0] = mmap(0, 4096, PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
337*d83cc019SAndroid Build Coastguard Worker igt_assert(page[0] != MAP_FAILED);
338*d83cc019SAndroid Build Coastguard Worker memcpy(page[0], &sseu, sizeof(sseu));
339*d83cc019SAndroid Build Coastguard Worker munmap(page[0], 4096);
340*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(page[0]);
341*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EFAULT);
342*d83cc019SAndroid Build Coastguard Worker
343*d83cc019SAndroid Build Coastguard Worker /* Straddle into unmapped area. */
344*d83cc019SAndroid Build Coastguard Worker page[0] = mmap(0, 8192, PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
345*d83cc019SAndroid Build Coastguard Worker igt_assert(page[0] != MAP_FAILED);
346*d83cc019SAndroid Build Coastguard Worker munmap(page[0], 8192);
347*d83cc019SAndroid Build Coastguard Worker page[0] = mmap(page[0], 4096,
348*d83cc019SAndroid Build Coastguard Worker PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
349*d83cc019SAndroid Build Coastguard Worker igt_assert(page[0] != MAP_FAILED);
350*d83cc019SAndroid Build Coastguard Worker page[1] = mmap((void *)((unsigned long)page[0] + 4096), 4096,
351*d83cc019SAndroid Build Coastguard Worker PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
352*d83cc019SAndroid Build Coastguard Worker igt_assert(page[1] != MAP_FAILED);
353*d83cc019SAndroid Build Coastguard Worker addr = page[1] - sizeof(sseu) + 4;
354*d83cc019SAndroid Build Coastguard Worker memcpy(addr, &sseu, sizeof(sseu));
355*d83cc019SAndroid Build Coastguard Worker munmap(page[1], 4096);
356*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(addr);
357*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EFAULT);
358*d83cc019SAndroid Build Coastguard Worker munmap(page[0], 4096);
359*d83cc019SAndroid Build Coastguard Worker
360*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, arg.ctx_id);
361*d83cc019SAndroid Build Coastguard Worker }
362*d83cc019SAndroid Build Coastguard Worker
363*d83cc019SAndroid Build Coastguard Worker /*
364*d83cc019SAndroid Build Coastguard Worker * Verify that ggtt mapped area can be used as the sseu pointer.
365*d83cc019SAndroid Build Coastguard Worker */
366*d83cc019SAndroid Build Coastguard Worker static void
test_ggtt_args(int fd)367*d83cc019SAndroid Build Coastguard Worker test_ggtt_args(int fd)
368*d83cc019SAndroid Build Coastguard Worker {
369*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param_sseu *sseu;
370*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param arg = {
371*d83cc019SAndroid Build Coastguard Worker .param = I915_CONTEXT_PARAM_SSEU,
372*d83cc019SAndroid Build Coastguard Worker .ctx_id = gem_context_create(fd),
373*d83cc019SAndroid Build Coastguard Worker .size = sizeof(*sseu),
374*d83cc019SAndroid Build Coastguard Worker };
375*d83cc019SAndroid Build Coastguard Worker uint32_t bo;
376*d83cc019SAndroid Build Coastguard Worker
377*d83cc019SAndroid Build Coastguard Worker bo = gem_create(fd, 4096);
378*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(gem_mmap__gtt(fd, bo, 4096,
379*d83cc019SAndroid Build Coastguard Worker PROT_READ | PROT_WRITE));
380*d83cc019SAndroid Build Coastguard Worker
381*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_get_param(fd, &arg), 0);
382*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), 0);
383*d83cc019SAndroid Build Coastguard Worker
384*d83cc019SAndroid Build Coastguard Worker munmap((void *)(uintptr_t)arg.value, 4096);
385*d83cc019SAndroid Build Coastguard Worker gem_close(fd, bo);
386*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, arg.ctx_id);
387*d83cc019SAndroid Build Coastguard Worker }
388*d83cc019SAndroid Build Coastguard Worker
389*d83cc019SAndroid Build Coastguard Worker /*
390*d83cc019SAndroid Build Coastguard Worker * Verify that invalid SSEU values are rejected.
391*d83cc019SAndroid Build Coastguard Worker */
392*d83cc019SAndroid Build Coastguard Worker static void
test_invalid_sseu(int fd)393*d83cc019SAndroid Build Coastguard Worker test_invalid_sseu(int fd)
394*d83cc019SAndroid Build Coastguard Worker {
395*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param_sseu device_sseu = { };
396*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param_sseu sseu = { };
397*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_param arg = {
398*d83cc019SAndroid Build Coastguard Worker .param = I915_CONTEXT_PARAM_SSEU,
399*d83cc019SAndroid Build Coastguard Worker .ctx_id = gem_context_create(fd),
400*d83cc019SAndroid Build Coastguard Worker .size = sizeof(sseu),
401*d83cc019SAndroid Build Coastguard Worker };
402*d83cc019SAndroid Build Coastguard Worker unsigned int i;
403*d83cc019SAndroid Build Coastguard Worker
404*d83cc019SAndroid Build Coastguard Worker /* Fetch the device defaults. */
405*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(&device_sseu);
406*d83cc019SAndroid Build Coastguard Worker gem_context_get_param(fd, &arg);
407*d83cc019SAndroid Build Coastguard Worker
408*d83cc019SAndroid Build Coastguard Worker arg.value = to_user_pointer(&sseu);
409*d83cc019SAndroid Build Coastguard Worker
410*d83cc019SAndroid Build Coastguard Worker /* Try all slice masks known to be invalid. */
411*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
412*d83cc019SAndroid Build Coastguard Worker for (i = 1; i <= (8 - __slice_count__); i++) {
413*d83cc019SAndroid Build Coastguard Worker sseu.slice_mask = mask_plus(__slice_mask__, i);
414*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
415*d83cc019SAndroid Build Coastguard Worker }
416*d83cc019SAndroid Build Coastguard Worker
417*d83cc019SAndroid Build Coastguard Worker /* 0 slices. */
418*d83cc019SAndroid Build Coastguard Worker sseu.slice_mask = 0;
419*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(-EINVAL, __gem_context_set_param(fd, &arg));
420*d83cc019SAndroid Build Coastguard Worker
421*d83cc019SAndroid Build Coastguard Worker /* Try all subslice masks known to be invalid. */
422*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
423*d83cc019SAndroid Build Coastguard Worker for (i = 1; i <= (8 - __subslice_count__); i++) {
424*d83cc019SAndroid Build Coastguard Worker sseu.subslice_mask = mask_plus(__subslice_mask__, i);
425*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
426*d83cc019SAndroid Build Coastguard Worker }
427*d83cc019SAndroid Build Coastguard Worker
428*d83cc019SAndroid Build Coastguard Worker /* 0 subslices. */
429*d83cc019SAndroid Build Coastguard Worker sseu.subslice_mask = 0;
430*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
431*d83cc019SAndroid Build Coastguard Worker
432*d83cc019SAndroid Build Coastguard Worker /* Try number of EUs superior to the max available. */
433*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
434*d83cc019SAndroid Build Coastguard Worker sseu.min_eus_per_subslice = device_sseu.max_eus_per_subslice + 1;
435*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
436*d83cc019SAndroid Build Coastguard Worker
437*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
438*d83cc019SAndroid Build Coastguard Worker sseu.max_eus_per_subslice = device_sseu.max_eus_per_subslice + 1;
439*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
440*d83cc019SAndroid Build Coastguard Worker
441*d83cc019SAndroid Build Coastguard Worker /* Try to program 0 max EUs. */
442*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
443*d83cc019SAndroid Build Coastguard Worker sseu.max_eus_per_subslice = 0;
444*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
445*d83cc019SAndroid Build Coastguard Worker
446*d83cc019SAndroid Build Coastguard Worker /* Min > max */
447*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
448*d83cc019SAndroid Build Coastguard Worker sseu.min_eus_per_subslice = sseu.max_eus_per_subslice;
449*d83cc019SAndroid Build Coastguard Worker sseu.max_eus_per_subslice = 1;
450*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
451*d83cc019SAndroid Build Coastguard Worker
452*d83cc019SAndroid Build Coastguard Worker if (__intel_gen__ != 11)
453*d83cc019SAndroid Build Coastguard Worker goto out;
454*d83cc019SAndroid Build Coastguard Worker
455*d83cc019SAndroid Build Coastguard Worker /* Subset of subslices but slice mask greater than one. */
456*d83cc019SAndroid Build Coastguard Worker if (__slice_count__ > 1) {
457*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
458*d83cc019SAndroid Build Coastguard Worker sseu.subslice_mask = mask_minus_one(sseu.subslice_mask);
459*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
460*d83cc019SAndroid Build Coastguard Worker }
461*d83cc019SAndroid Build Coastguard Worker
462*d83cc019SAndroid Build Coastguard Worker /* Odd subslices above four. */
463*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
464*d83cc019SAndroid Build Coastguard Worker sseu.slice_mask = 0x1;
465*d83cc019SAndroid Build Coastguard Worker sseu.subslice_mask = mask_minus_one(sseu.subslice_mask);
466*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
467*d83cc019SAndroid Build Coastguard Worker
468*d83cc019SAndroid Build Coastguard Worker /* More than half subslices with one slice. */
469*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
470*d83cc019SAndroid Build Coastguard Worker sseu.slice_mask = 0x1;
471*d83cc019SAndroid Build Coastguard Worker sseu.subslice_mask = mask_minus(sseu.subslice_mask,
472*d83cc019SAndroid Build Coastguard Worker __subslice_count__ / 2 - 1);
473*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
474*d83cc019SAndroid Build Coastguard Worker
475*d83cc019SAndroid Build Coastguard Worker /* VME */
476*d83cc019SAndroid Build Coastguard Worker
477*d83cc019SAndroid Build Coastguard Worker /* Slice count between one and max. */
478*d83cc019SAndroid Build Coastguard Worker if (__slice_count__ > 2) {
479*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
480*d83cc019SAndroid Build Coastguard Worker sseu.slice_mask = mask_minus_one(sseu.slice_mask);
481*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
482*d83cc019SAndroid Build Coastguard Worker }
483*d83cc019SAndroid Build Coastguard Worker
484*d83cc019SAndroid Build Coastguard Worker /* Less than half subslices with one slice. */
485*d83cc019SAndroid Build Coastguard Worker sseu = device_sseu;
486*d83cc019SAndroid Build Coastguard Worker sseu.slice_mask = 0x1;
487*d83cc019SAndroid Build Coastguard Worker sseu.subslice_mask = mask_minus(sseu.subslice_mask,
488*d83cc019SAndroid Build Coastguard Worker __subslice_count__ / 2 + 1);
489*d83cc019SAndroid Build Coastguard Worker igt_assert_eq(__gem_context_set_param(fd, &arg), -EINVAL);
490*d83cc019SAndroid Build Coastguard Worker
491*d83cc019SAndroid Build Coastguard Worker out:
492*d83cc019SAndroid Build Coastguard Worker gem_context_destroy(fd, arg.ctx_id);
493*d83cc019SAndroid Build Coastguard Worker }
494*d83cc019SAndroid Build Coastguard Worker
495*d83cc019SAndroid Build Coastguard Worker igt_main
496*d83cc019SAndroid Build Coastguard Worker {
497*d83cc019SAndroid Build Coastguard Worker int fd;
498*d83cc019SAndroid Build Coastguard Worker
499*d83cc019SAndroid Build Coastguard Worker igt_fixture {
500*d83cc019SAndroid Build Coastguard Worker fd = drm_open_driver(DRIVER_INTEL);
501*d83cc019SAndroid Build Coastguard Worker igt_require_gem(fd);
502*d83cc019SAndroid Build Coastguard Worker
503*d83cc019SAndroid Build Coastguard Worker __intel_devid__ = intel_get_drm_devid(fd);
504*d83cc019SAndroid Build Coastguard Worker __intel_gen__ = intel_gen(__intel_devid__);
505*d83cc019SAndroid Build Coastguard Worker
506*d83cc019SAndroid Build Coastguard Worker igt_require(kernel_has_per_context_sseu_support(fd));
507*d83cc019SAndroid Build Coastguard Worker }
508*d83cc019SAndroid Build Coastguard Worker
509*d83cc019SAndroid Build Coastguard Worker igt_subtest_group {
510*d83cc019SAndroid Build Coastguard Worker igt_fixture {
511*d83cc019SAndroid Build Coastguard Worker drm_i915_getparam_t gp;
512*d83cc019SAndroid Build Coastguard Worker
513*d83cc019SAndroid Build Coastguard Worker gp.param = I915_PARAM_SLICE_MASK;
514*d83cc019SAndroid Build Coastguard Worker gp.value = (int *) &__slice_mask__;
515*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
516*d83cc019SAndroid Build Coastguard Worker __slice_count__ = __builtin_popcount(__slice_mask__);
517*d83cc019SAndroid Build Coastguard Worker
518*d83cc019SAndroid Build Coastguard Worker gp.param = I915_PARAM_SUBSLICE_MASK;
519*d83cc019SAndroid Build Coastguard Worker gp.value = (int *) &__subslice_mask__;
520*d83cc019SAndroid Build Coastguard Worker do_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
521*d83cc019SAndroid Build Coastguard Worker __subslice_count__ =
522*d83cc019SAndroid Build Coastguard Worker __builtin_popcount(__subslice_mask__);
523*d83cc019SAndroid Build Coastguard Worker }
524*d83cc019SAndroid Build Coastguard Worker
525*d83cc019SAndroid Build Coastguard Worker igt_subtest("invalid-args")
526*d83cc019SAndroid Build Coastguard Worker test_invalid_args(fd);
527*d83cc019SAndroid Build Coastguard Worker
528*d83cc019SAndroid Build Coastguard Worker igt_subtest("invalid-sseu")
529*d83cc019SAndroid Build Coastguard Worker test_invalid_sseu(fd);
530*d83cc019SAndroid Build Coastguard Worker
531*d83cc019SAndroid Build Coastguard Worker igt_subtest("ggtt-args")
532*d83cc019SAndroid Build Coastguard Worker test_ggtt_args(fd);
533*d83cc019SAndroid Build Coastguard Worker
534*d83cc019SAndroid Build Coastguard Worker igt_subtest("engines")
535*d83cc019SAndroid Build Coastguard Worker test_engines(fd);
536*d83cc019SAndroid Build Coastguard Worker }
537*d83cc019SAndroid Build Coastguard Worker
538*d83cc019SAndroid Build Coastguard Worker igt_fixture {
539*d83cc019SAndroid Build Coastguard Worker close(fd);
540*d83cc019SAndroid Build Coastguard Worker }
541*d83cc019SAndroid Build Coastguard Worker }
542