xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/gem_exec_parse.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2013 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 
25*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
26*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
27*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
29*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
30*d83cc019SAndroid Build Coastguard Worker 
31*d83cc019SAndroid Build Coastguard Worker #include <drm.h>
32*d83cc019SAndroid Build Coastguard Worker 
33*d83cc019SAndroid Build Coastguard Worker #ifndef I915_PARAM_CMD_PARSER_VERSION
34*d83cc019SAndroid Build Coastguard Worker #define I915_PARAM_CMD_PARSER_VERSION       28
35*d83cc019SAndroid Build Coastguard Worker #endif
36*d83cc019SAndroid Build Coastguard Worker 
37*d83cc019SAndroid Build Coastguard Worker #define DERRMR 0x44050
38*d83cc019SAndroid Build Coastguard Worker #define OASTATUS2 0x2368
39*d83cc019SAndroid Build Coastguard Worker #define OACONTROL 0x2360
40*d83cc019SAndroid Build Coastguard Worker #define SO_WRITE_OFFSET_0 0x5280
41*d83cc019SAndroid Build Coastguard Worker 
42*d83cc019SAndroid Build Coastguard Worker #define HSW_CS_GPR(n) (0x2600 + 8*(n))
43*d83cc019SAndroid Build Coastguard Worker #define HSW_CS_GPR0 HSW_CS_GPR(0)
44*d83cc019SAndroid Build Coastguard Worker #define HSW_CS_GPR1 HSW_CS_GPR(1)
45*d83cc019SAndroid Build Coastguard Worker 
46*d83cc019SAndroid Build Coastguard Worker /* To help craft commands known to be invalid across all engines */
47*d83cc019SAndroid Build Coastguard Worker #define INSTR_CLIENT_SHIFT	29
48*d83cc019SAndroid Build Coastguard Worker #define   INSTR_INVALID_CLIENT  0x7
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker #define MI_LOAD_REGISTER_REG (0x2a << 23)
51*d83cc019SAndroid Build Coastguard Worker #define MI_STORE_REGISTER_MEM (0x24 << 23)
52*d83cc019SAndroid Build Coastguard Worker #define MI_ARB_ON_OFF (0x8 << 23)
53*d83cc019SAndroid Build Coastguard Worker #define MI_DISPLAY_FLIP ((0x14 << 23) | 1)
54*d83cc019SAndroid Build Coastguard Worker 
55*d83cc019SAndroid Build Coastguard Worker #define GFX_OP_PIPE_CONTROL	((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
56*d83cc019SAndroid Build Coastguard Worker #define   PIPE_CONTROL_QW_WRITE	(1<<14)
57*d83cc019SAndroid Build Coastguard Worker #define   PIPE_CONTROL_LRI_POST_OP (1<<23)
58*d83cc019SAndroid Build Coastguard Worker 
59*d83cc019SAndroid Build Coastguard Worker static int parser_version;
60*d83cc019SAndroid Build Coastguard Worker 
command_parser_version(int fd)61*d83cc019SAndroid Build Coastguard Worker static int command_parser_version(int fd)
62*d83cc019SAndroid Build Coastguard Worker {
63*d83cc019SAndroid Build Coastguard Worker 	int version = -1;
64*d83cc019SAndroid Build Coastguard Worker 	drm_i915_getparam_t gp;
65*d83cc019SAndroid Build Coastguard Worker 
66*d83cc019SAndroid Build Coastguard Worker 	gp.param = I915_PARAM_CMD_PARSER_VERSION;
67*d83cc019SAndroid Build Coastguard Worker 	gp.value = &version;
68*d83cc019SAndroid Build Coastguard Worker 
69*d83cc019SAndroid Build Coastguard Worker 	if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp) == 0)
70*d83cc019SAndroid Build Coastguard Worker 		return version;
71*d83cc019SAndroid Build Coastguard Worker 
72*d83cc019SAndroid Build Coastguard Worker 	return -1;
73*d83cc019SAndroid Build Coastguard Worker }
74*d83cc019SAndroid Build Coastguard Worker 
__exec_batch_patched(int fd,uint32_t cmd_bo,uint32_t * cmds,int size,int patch_offset)75*d83cc019SAndroid Build Coastguard Worker static uint64_t __exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds,
76*d83cc019SAndroid Build Coastguard Worker 				     int size, int patch_offset)
77*d83cc019SAndroid Build Coastguard Worker {
78*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
79*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[2];
80*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc[1];
81*d83cc019SAndroid Build Coastguard Worker 
82*d83cc019SAndroid Build Coastguard Worker 	uint32_t target_bo = gem_create(fd, 4096);
83*d83cc019SAndroid Build Coastguard Worker 	uint64_t actual_value = 0;
84*d83cc019SAndroid Build Coastguard Worker 
85*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, cmd_bo, 0, cmds, size);
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
88*d83cc019SAndroid Build Coastguard Worker 	obj[0].handle = target_bo;
89*d83cc019SAndroid Build Coastguard Worker 	obj[1].handle = cmd_bo;
90*d83cc019SAndroid Build Coastguard Worker 
91*d83cc019SAndroid Build Coastguard Worker 	memset(reloc, 0, sizeof(reloc));
92*d83cc019SAndroid Build Coastguard Worker 	reloc[0].offset = patch_offset;
93*d83cc019SAndroid Build Coastguard Worker 	reloc[0].target_handle = obj[0].handle;
94*d83cc019SAndroid Build Coastguard Worker 	reloc[0].delta = 0;
95*d83cc019SAndroid Build Coastguard Worker 	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
96*d83cc019SAndroid Build Coastguard Worker 	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
97*d83cc019SAndroid Build Coastguard Worker 	obj[1].relocs_ptr = to_user_pointer(reloc);
98*d83cc019SAndroid Build Coastguard Worker 	obj[1].relocation_count = 1;
99*d83cc019SAndroid Build Coastguard Worker 
100*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
101*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj);
102*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 2;
103*d83cc019SAndroid Build Coastguard Worker 	execbuf.batch_len = size;
104*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = I915_EXEC_RENDER;
105*d83cc019SAndroid Build Coastguard Worker 
106*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
107*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, cmd_bo);
108*d83cc019SAndroid Build Coastguard Worker 
109*d83cc019SAndroid Build Coastguard Worker 	gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value));
110*d83cc019SAndroid Build Coastguard Worker 
111*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, target_bo);
112*d83cc019SAndroid Build Coastguard Worker 
113*d83cc019SAndroid Build Coastguard Worker 	return actual_value;
114*d83cc019SAndroid Build Coastguard Worker }
115*d83cc019SAndroid Build Coastguard Worker 
exec_batch_patched(int fd,uint32_t cmd_bo,uint32_t * cmds,int size,int patch_offset,uint64_t expected_value)116*d83cc019SAndroid Build Coastguard Worker static void exec_batch_patched(int fd, uint32_t cmd_bo, uint32_t *cmds,
117*d83cc019SAndroid Build Coastguard Worker 			       int size, int patch_offset,
118*d83cc019SAndroid Build Coastguard Worker 			       uint64_t expected_value)
119*d83cc019SAndroid Build Coastguard Worker {
120*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__exec_batch_patched(fd, cmd_bo, cmds,
121*d83cc019SAndroid Build Coastguard Worker 					   size, patch_offset),
122*d83cc019SAndroid Build Coastguard Worker 		      expected_value);
123*d83cc019SAndroid Build Coastguard Worker }
124*d83cc019SAndroid Build Coastguard Worker 
__exec_batch(int fd,uint32_t cmd_bo,uint32_t * cmds,int size,int ring)125*d83cc019SAndroid Build Coastguard Worker static int __exec_batch(int fd, uint32_t cmd_bo, uint32_t *cmds,
126*d83cc019SAndroid Build Coastguard Worker 			int size, int ring)
127*d83cc019SAndroid Build Coastguard Worker {
128*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
129*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[1];
130*d83cc019SAndroid Build Coastguard Worker 
131*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, cmd_bo, 0, cmds, size);
132*d83cc019SAndroid Build Coastguard Worker 
133*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
134*d83cc019SAndroid Build Coastguard Worker 	obj[0].handle = cmd_bo;
135*d83cc019SAndroid Build Coastguard Worker 
136*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
137*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj);
138*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
139*d83cc019SAndroid Build Coastguard Worker 	execbuf.batch_len = size;
140*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = ring;
141*d83cc019SAndroid Build Coastguard Worker 
142*d83cc019SAndroid Build Coastguard Worker 	return __gem_execbuf(fd, &execbuf);
143*d83cc019SAndroid Build Coastguard Worker }
144*d83cc019SAndroid Build Coastguard Worker #define exec_batch(fd, bo, cmds, sz, ring, expected) \
145*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__exec_batch(fd, bo, cmds, sz, ring), expected)
146*d83cc019SAndroid Build Coastguard Worker 
exec_split_batch(int fd,uint32_t * cmds,int size,int ring,int expected_ret)147*d83cc019SAndroid Build Coastguard Worker static void exec_split_batch(int fd, uint32_t *cmds,
148*d83cc019SAndroid Build Coastguard Worker 			     int size, int ring, int expected_ret)
149*d83cc019SAndroid Build Coastguard Worker {
150*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
151*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[1];
152*d83cc019SAndroid Build Coastguard Worker 	uint32_t cmd_bo;
153*d83cc019SAndroid Build Coastguard Worker 	uint32_t noop[1024] = { 0 };
154*d83cc019SAndroid Build Coastguard Worker 	const int alloc_size = 4096 * 2;
155*d83cc019SAndroid Build Coastguard Worker 	const int actual_start_offset = 4096-sizeof(uint32_t);
156*d83cc019SAndroid Build Coastguard Worker 
157*d83cc019SAndroid Build Coastguard Worker 	/* Allocate and fill a 2-page batch with noops */
158*d83cc019SAndroid Build Coastguard Worker 	cmd_bo = gem_create(fd, alloc_size);
159*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, cmd_bo, 0, noop, sizeof(noop));
160*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, cmd_bo, 4096, noop, sizeof(noop));
161*d83cc019SAndroid Build Coastguard Worker 
162*d83cc019SAndroid Build Coastguard Worker 	/* Write the provided commands such that the first dword
163*d83cc019SAndroid Build Coastguard Worker 	 * of the command buffer is the last dword of the first
164*d83cc019SAndroid Build Coastguard Worker 	 * page (i.e. the command is split across the two pages).
165*d83cc019SAndroid Build Coastguard Worker 	 */
166*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, cmd_bo, actual_start_offset, cmds, size);
167*d83cc019SAndroid Build Coastguard Worker 
168*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
169*d83cc019SAndroid Build Coastguard Worker 	obj[0].handle = cmd_bo;
170*d83cc019SAndroid Build Coastguard Worker 
171*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
172*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj);
173*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
174*d83cc019SAndroid Build Coastguard Worker 	/* NB: We want batch_start_offset and batch_len to point to the block
175*d83cc019SAndroid Build Coastguard Worker 	 * of the actual commands (i.e. at the last dword of the first page),
176*d83cc019SAndroid Build Coastguard Worker 	 * but have to adjust both the start offset and length to meet the
177*d83cc019SAndroid Build Coastguard Worker 	 * kernel driver's requirements on the alignment of those fields.
178*d83cc019SAndroid Build Coastguard Worker 	 */
179*d83cc019SAndroid Build Coastguard Worker 	execbuf.batch_start_offset = actual_start_offset & ~0x7;
180*d83cc019SAndroid Build Coastguard Worker 	execbuf.batch_len =
181*d83cc019SAndroid Build Coastguard Worker 		ALIGN(size + actual_start_offset - execbuf.batch_start_offset,
182*d83cc019SAndroid Build Coastguard Worker 		      0x8);
183*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = ring;
184*d83cc019SAndroid Build Coastguard Worker 
185*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(__gem_execbuf(fd, &execbuf), expected_ret);
186*d83cc019SAndroid Build Coastguard Worker 
187*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, cmd_bo);
188*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, cmd_bo);
189*d83cc019SAndroid Build Coastguard Worker }
190*d83cc019SAndroid Build Coastguard Worker 
exec_batch_chained(int fd,uint32_t cmd_bo,uint32_t * cmds,int size,int patch_offset,uint64_t expected_value)191*d83cc019SAndroid Build Coastguard Worker static void exec_batch_chained(int fd, uint32_t cmd_bo, uint32_t *cmds,
192*d83cc019SAndroid Build Coastguard Worker 			       int size, int patch_offset,
193*d83cc019SAndroid Build Coastguard Worker 			       uint64_t expected_value)
194*d83cc019SAndroid Build Coastguard Worker {
195*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
196*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[3];
197*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry reloc[1];
198*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_relocation_entry first_level_reloc;
199*d83cc019SAndroid Build Coastguard Worker 
200*d83cc019SAndroid Build Coastguard Worker 	uint32_t target_bo = gem_create(fd, 4096);
201*d83cc019SAndroid Build Coastguard Worker 	uint32_t first_level_bo = gem_create(fd, 4096);
202*d83cc019SAndroid Build Coastguard Worker 	uint64_t actual_value = 0;
203*d83cc019SAndroid Build Coastguard Worker 
204*d83cc019SAndroid Build Coastguard Worker 	static uint32_t first_level_cmds[] = {
205*d83cc019SAndroid Build Coastguard Worker 		MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965,
206*d83cc019SAndroid Build Coastguard Worker 		0,
207*d83cc019SAndroid Build Coastguard Worker 		MI_BATCH_BUFFER_END,
208*d83cc019SAndroid Build Coastguard Worker 		0,
209*d83cc019SAndroid Build Coastguard Worker 	};
210*d83cc019SAndroid Build Coastguard Worker 
211*d83cc019SAndroid Build Coastguard Worker 	if (IS_HASWELL(intel_get_drm_devid(fd)))
212*d83cc019SAndroid Build Coastguard Worker 		first_level_cmds[0] |= MI_BATCH_NON_SECURE_HSW;
213*d83cc019SAndroid Build Coastguard Worker 
214*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, first_level_bo, 0,
215*d83cc019SAndroid Build Coastguard Worker 		  first_level_cmds, sizeof(first_level_cmds));
216*d83cc019SAndroid Build Coastguard Worker 	gem_write(fd, cmd_bo, 0, cmds, size);
217*d83cc019SAndroid Build Coastguard Worker 
218*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
219*d83cc019SAndroid Build Coastguard Worker 	obj[0].handle = target_bo;
220*d83cc019SAndroid Build Coastguard Worker 	obj[1].handle = cmd_bo;
221*d83cc019SAndroid Build Coastguard Worker 	obj[2].handle = first_level_bo;
222*d83cc019SAndroid Build Coastguard Worker 
223*d83cc019SAndroid Build Coastguard Worker 	memset(reloc, 0, sizeof(reloc));
224*d83cc019SAndroid Build Coastguard Worker 	reloc[0].offset = patch_offset;
225*d83cc019SAndroid Build Coastguard Worker 	reloc[0].delta = 0;
226*d83cc019SAndroid Build Coastguard Worker 	reloc[0].target_handle = target_bo;
227*d83cc019SAndroid Build Coastguard Worker 	reloc[0].read_domains = I915_GEM_DOMAIN_COMMAND;
228*d83cc019SAndroid Build Coastguard Worker 	reloc[0].write_domain = I915_GEM_DOMAIN_COMMAND;
229*d83cc019SAndroid Build Coastguard Worker 	obj[1].relocation_count = 1;
230*d83cc019SAndroid Build Coastguard Worker 	obj[1].relocs_ptr = to_user_pointer(&reloc);
231*d83cc019SAndroid Build Coastguard Worker 
232*d83cc019SAndroid Build Coastguard Worker 	memset(&first_level_reloc, 0, sizeof(first_level_reloc));
233*d83cc019SAndroid Build Coastguard Worker 	first_level_reloc.offset = 4;
234*d83cc019SAndroid Build Coastguard Worker 	first_level_reloc.delta = 0;
235*d83cc019SAndroid Build Coastguard Worker 	first_level_reloc.target_handle = cmd_bo;
236*d83cc019SAndroid Build Coastguard Worker 	first_level_reloc.read_domains = I915_GEM_DOMAIN_COMMAND;
237*d83cc019SAndroid Build Coastguard Worker 	first_level_reloc.write_domain = 0;
238*d83cc019SAndroid Build Coastguard Worker 	obj[2].relocation_count = 1;
239*d83cc019SAndroid Build Coastguard Worker 	obj[2].relocs_ptr = to_user_pointer(&first_level_reloc);
240*d83cc019SAndroid Build Coastguard Worker 
241*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
242*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffers_ptr = to_user_pointer(obj);
243*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 3;
244*d83cc019SAndroid Build Coastguard Worker 	execbuf.batch_len = sizeof(first_level_cmds);
245*d83cc019SAndroid Build Coastguard Worker 	execbuf.flags = I915_EXEC_RENDER;
246*d83cc019SAndroid Build Coastguard Worker 
247*d83cc019SAndroid Build Coastguard Worker 	gem_execbuf(fd, &execbuf);
248*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, cmd_bo);
249*d83cc019SAndroid Build Coastguard Worker 
250*d83cc019SAndroid Build Coastguard Worker 	gem_read(fd,target_bo, 0, &actual_value, sizeof(actual_value));
251*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(expected_value, actual_value);
252*d83cc019SAndroid Build Coastguard Worker 
253*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, first_level_bo);
254*d83cc019SAndroid Build Coastguard Worker 	gem_close(fd, target_bo);
255*d83cc019SAndroid Build Coastguard Worker }
256*d83cc019SAndroid Build Coastguard Worker 
257*d83cc019SAndroid Build Coastguard Worker /* Be careful to take into account what register bits we can store and read
258*d83cc019SAndroid Build Coastguard Worker  * from...
259*d83cc019SAndroid Build Coastguard Worker  */
260*d83cc019SAndroid Build Coastguard Worker struct test_lri {
261*d83cc019SAndroid Build Coastguard Worker 	const char *name; /* register name for debug info */
262*d83cc019SAndroid Build Coastguard Worker 	uint32_t reg; /* address to test */
263*d83cc019SAndroid Build Coastguard Worker 	uint32_t read_mask; /* ignore things like HW status bits */
264*d83cc019SAndroid Build Coastguard Worker 	uint32_t init_val; /* initial identifiable value to set without LRI */
265*d83cc019SAndroid Build Coastguard Worker 	uint32_t test_val; /* value to attempt loading via LRI command */
266*d83cc019SAndroid Build Coastguard Worker 	bool whitelisted; /* expect to become NOOP / fail if not whitelisted */
267*d83cc019SAndroid Build Coastguard Worker 	int min_ver; /* required command parser version to test */
268*d83cc019SAndroid Build Coastguard Worker };
269*d83cc019SAndroid Build Coastguard Worker 
270*d83cc019SAndroid Build Coastguard Worker static void
test_lri(int fd,uint32_t handle,struct test_lri * test)271*d83cc019SAndroid Build Coastguard Worker test_lri(int fd, uint32_t handle, struct test_lri *test)
272*d83cc019SAndroid Build Coastguard Worker {
273*d83cc019SAndroid Build Coastguard Worker 	uint32_t lri[] = {
274*d83cc019SAndroid Build Coastguard Worker 		MI_LOAD_REGISTER_IMM,
275*d83cc019SAndroid Build Coastguard Worker 		test->reg,
276*d83cc019SAndroid Build Coastguard Worker 		test->test_val,
277*d83cc019SAndroid Build Coastguard Worker 		MI_BATCH_BUFFER_END,
278*d83cc019SAndroid Build Coastguard Worker 	};
279*d83cc019SAndroid Build Coastguard Worker 	int bad_lri_errno = parser_version >= 8 ? 0 : -EINVAL;
280*d83cc019SAndroid Build Coastguard Worker 	int expected_errno = test->whitelisted ? 0 : bad_lri_errno;
281*d83cc019SAndroid Build Coastguard Worker 	uint32_t expect = test->whitelisted ? test->test_val : test->init_val;
282*d83cc019SAndroid Build Coastguard Worker 
283*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Testing %s LRI: addr=%x, val=%x, expected errno=%d, expected val=%x\n",
284*d83cc019SAndroid Build Coastguard Worker 		  test->name, test->reg, test->test_val,
285*d83cc019SAndroid Build Coastguard Worker 		  expected_errno, expect);
286*d83cc019SAndroid Build Coastguard Worker 
287*d83cc019SAndroid Build Coastguard Worker 	intel_register_write(test->reg, test->init_val);
288*d83cc019SAndroid Build Coastguard Worker 
289*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u32((intel_register_read(test->reg) &
290*d83cc019SAndroid Build Coastguard Worker 			   test->read_mask),
291*d83cc019SAndroid Build Coastguard Worker 			  test->init_val);
292*d83cc019SAndroid Build Coastguard Worker 
293*d83cc019SAndroid Build Coastguard Worker 	exec_batch(fd, handle,
294*d83cc019SAndroid Build Coastguard Worker 		   lri, sizeof(lri),
295*d83cc019SAndroid Build Coastguard Worker 		   I915_EXEC_RENDER,
296*d83cc019SAndroid Build Coastguard Worker 		   expected_errno);
297*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, handle);
298*d83cc019SAndroid Build Coastguard Worker 
299*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq_u32((intel_register_read(test->reg) &
300*d83cc019SAndroid Build Coastguard Worker 			   test->read_mask),
301*d83cc019SAndroid Build Coastguard Worker 			  expect);
302*d83cc019SAndroid Build Coastguard Worker }
303*d83cc019SAndroid Build Coastguard Worker 
test_allocations(int fd)304*d83cc019SAndroid Build Coastguard Worker static void test_allocations(int fd)
305*d83cc019SAndroid Build Coastguard Worker {
306*d83cc019SAndroid Build Coastguard Worker 	const uint32_t bbe = MI_BATCH_BUFFER_END;
307*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 execbuf;
308*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj[17];
309*d83cc019SAndroid Build Coastguard Worker 	unsigned long count;
310*d83cc019SAndroid Build Coastguard Worker 
311*d83cc019SAndroid Build Coastguard Worker 	intel_require_memory(2, 1ull<<(12 + ARRAY_SIZE(obj)), CHECK_RAM);
312*d83cc019SAndroid Build Coastguard Worker 
313*d83cc019SAndroid Build Coastguard Worker 	memset(obj, 0, sizeof(obj));
314*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < ARRAY_SIZE(obj); i++) {
315*d83cc019SAndroid Build Coastguard Worker 		uint64_t size = 1ull << (12 + i);
316*d83cc019SAndroid Build Coastguard Worker 
317*d83cc019SAndroid Build Coastguard Worker 		obj[i].handle = gem_create(fd, size);
318*d83cc019SAndroid Build Coastguard Worker 		for (uint64_t page = 4096; page <= size; page += 4096)
319*d83cc019SAndroid Build Coastguard Worker 			gem_write(fd, obj[i].handle,
320*d83cc019SAndroid Build Coastguard Worker 				  page - sizeof(bbe), &bbe, sizeof(bbe));
321*d83cc019SAndroid Build Coastguard Worker 	}
322*d83cc019SAndroid Build Coastguard Worker 
323*d83cc019SAndroid Build Coastguard Worker 	memset(&execbuf, 0, sizeof(execbuf));
324*d83cc019SAndroid Build Coastguard Worker 	execbuf.buffer_count = 1;
325*d83cc019SAndroid Build Coastguard Worker 
326*d83cc019SAndroid Build Coastguard Worker 	count = 0;
327*d83cc019SAndroid Build Coastguard Worker 	igt_until_timeout(20) {
328*d83cc019SAndroid Build Coastguard Worker 		int i = rand() % ARRAY_SIZE(obj);
329*d83cc019SAndroid Build Coastguard Worker 		execbuf.buffers_ptr = to_user_pointer(&obj[i]);
330*d83cc019SAndroid Build Coastguard Worker 		execbuf.batch_start_offset = (rand() % (1ull<<i)) << 12;
331*d83cc019SAndroid Build Coastguard Worker 		execbuf.batch_start_offset += 64 * (rand() % 64);
332*d83cc019SAndroid Build Coastguard Worker 		execbuf.batch_len = (1ull<<(12+i)) - execbuf.batch_start_offset;
333*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(fd, &execbuf);
334*d83cc019SAndroid Build Coastguard Worker 		count++;
335*d83cc019SAndroid Build Coastguard Worker 	}
336*d83cc019SAndroid Build Coastguard Worker 	igt_info("Submitted %lu execbufs\n", count);
337*d83cc019SAndroid Build Coastguard Worker 	igt_drop_caches_set(fd, DROP_RESET_ACTIVE); /* Cancel the queued work */
338*d83cc019SAndroid Build Coastguard Worker 
339*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0; i < ARRAY_SIZE(obj); i++) {
340*d83cc019SAndroid Build Coastguard Worker 		gem_sync(fd, obj[i].handle);
341*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, obj[i].handle);
342*d83cc019SAndroid Build Coastguard Worker 	}
343*d83cc019SAndroid Build Coastguard Worker }
344*d83cc019SAndroid Build Coastguard Worker 
hsw_load_register_reg(void)345*d83cc019SAndroid Build Coastguard Worker static void hsw_load_register_reg(void)
346*d83cc019SAndroid Build Coastguard Worker {
347*d83cc019SAndroid Build Coastguard Worker 	uint32_t init_gpr0[16] = {
348*d83cc019SAndroid Build Coastguard Worker 		MI_LOAD_REGISTER_IMM | (3 - 2),
349*d83cc019SAndroid Build Coastguard Worker 		HSW_CS_GPR0,
350*d83cc019SAndroid Build Coastguard Worker 		0xabcdabc0, /* leave [1:0] zero */
351*d83cc019SAndroid Build Coastguard Worker 		MI_BATCH_BUFFER_END,
352*d83cc019SAndroid Build Coastguard Worker 	};
353*d83cc019SAndroid Build Coastguard Worker 	uint32_t store_gpr0[16] = {
354*d83cc019SAndroid Build Coastguard Worker 		MI_STORE_REGISTER_MEM | (3 - 2),
355*d83cc019SAndroid Build Coastguard Worker 		HSW_CS_GPR0,
356*d83cc019SAndroid Build Coastguard Worker 		0, /* reloc*/
357*d83cc019SAndroid Build Coastguard Worker 		MI_BATCH_BUFFER_END,
358*d83cc019SAndroid Build Coastguard Worker 	};
359*d83cc019SAndroid Build Coastguard Worker 	uint32_t do_lrr[16] = {
360*d83cc019SAndroid Build Coastguard Worker 		MI_LOAD_REGISTER_REG | (3 - 2),
361*d83cc019SAndroid Build Coastguard Worker 		0, /* [1] = src */
362*d83cc019SAndroid Build Coastguard Worker 		HSW_CS_GPR0, /* dst */
363*d83cc019SAndroid Build Coastguard Worker 		MI_BATCH_BUFFER_END,
364*d83cc019SAndroid Build Coastguard Worker 	};
365*d83cc019SAndroid Build Coastguard Worker 	uint32_t allowed_regs[] = {
366*d83cc019SAndroid Build Coastguard Worker 		HSW_CS_GPR1,
367*d83cc019SAndroid Build Coastguard Worker 		SO_WRITE_OFFSET_0,
368*d83cc019SAndroid Build Coastguard Worker 	};
369*d83cc019SAndroid Build Coastguard Worker 	uint32_t disallowed_regs[] = {
370*d83cc019SAndroid Build Coastguard Worker 		0,
371*d83cc019SAndroid Build Coastguard Worker 		OACONTROL, /* filtered */
372*d83cc019SAndroid Build Coastguard Worker 		DERRMR, /* master only */
373*d83cc019SAndroid Build Coastguard Worker 		0x2038, /* RING_START: invalid */
374*d83cc019SAndroid Build Coastguard Worker 	};
375*d83cc019SAndroid Build Coastguard Worker 	int fd;
376*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
377*d83cc019SAndroid Build Coastguard Worker 	int bad_lrr_errno = parser_version >= 8 ? 0 : -EINVAL;
378*d83cc019SAndroid Build Coastguard Worker 
379*d83cc019SAndroid Build Coastguard Worker 	/* Open again to get a non-master file descriptor */
380*d83cc019SAndroid Build Coastguard Worker 	fd = drm_open_driver(DRIVER_INTEL);
381*d83cc019SAndroid Build Coastguard Worker 
382*d83cc019SAndroid Build Coastguard Worker 	igt_require(IS_HASWELL(intel_get_drm_devid(fd)));
383*d83cc019SAndroid Build Coastguard Worker 	igt_require(parser_version >= 7);
384*d83cc019SAndroid Build Coastguard Worker 
385*d83cc019SAndroid Build Coastguard Worker 	handle = gem_create(fd, 4096);
386*d83cc019SAndroid Build Coastguard Worker 
387*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0 ; i < ARRAY_SIZE(allowed_regs); i++) {
388*d83cc019SAndroid Build Coastguard Worker 		uint32_t var;
389*d83cc019SAndroid Build Coastguard Worker 
390*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle, init_gpr0, sizeof(init_gpr0),
391*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
392*d83cc019SAndroid Build Coastguard Worker 			   0);
393*d83cc019SAndroid Build Coastguard Worker 		exec_batch_patched(fd, handle,
394*d83cc019SAndroid Build Coastguard Worker 				   store_gpr0, sizeof(store_gpr0),
395*d83cc019SAndroid Build Coastguard Worker 				   2 * sizeof(uint32_t), /* reloc */
396*d83cc019SAndroid Build Coastguard Worker 				   0xabcdabc0);
397*d83cc019SAndroid Build Coastguard Worker 		do_lrr[1] = allowed_regs[i];
398*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle, do_lrr, sizeof(do_lrr),
399*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
400*d83cc019SAndroid Build Coastguard Worker 			   0);
401*d83cc019SAndroid Build Coastguard Worker 		var = __exec_batch_patched(fd, handle,
402*d83cc019SAndroid Build Coastguard Worker 					   store_gpr0, sizeof(store_gpr0),
403*d83cc019SAndroid Build Coastguard Worker 					   2 * sizeof(uint32_t)); /* reloc */
404*d83cc019SAndroid Build Coastguard Worker 		igt_assert_neq(var, 0xabcdabc0);
405*d83cc019SAndroid Build Coastguard Worker 	}
406*d83cc019SAndroid Build Coastguard Worker 
407*d83cc019SAndroid Build Coastguard Worker 	for (int i = 0 ; i < ARRAY_SIZE(disallowed_regs); i++) {
408*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle, init_gpr0, sizeof(init_gpr0),
409*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
410*d83cc019SAndroid Build Coastguard Worker 			   0);
411*d83cc019SAndroid Build Coastguard Worker 		exec_batch_patched(fd, handle,
412*d83cc019SAndroid Build Coastguard Worker 				   store_gpr0, sizeof(store_gpr0),
413*d83cc019SAndroid Build Coastguard Worker 				   2 * sizeof(uint32_t), /* reloc */
414*d83cc019SAndroid Build Coastguard Worker 				   0xabcdabc0);
415*d83cc019SAndroid Build Coastguard Worker 		do_lrr[1] = disallowed_regs[i];
416*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle, do_lrr, sizeof(do_lrr),
417*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
418*d83cc019SAndroid Build Coastguard Worker 			   bad_lrr_errno);
419*d83cc019SAndroid Build Coastguard Worker 		exec_batch_patched(fd, handle,
420*d83cc019SAndroid Build Coastguard Worker 				   store_gpr0, sizeof(store_gpr0),
421*d83cc019SAndroid Build Coastguard Worker 				   2 * sizeof(uint32_t), /* reloc */
422*d83cc019SAndroid Build Coastguard Worker 				   0xabcdabc0);
423*d83cc019SAndroid Build Coastguard Worker 	}
424*d83cc019SAndroid Build Coastguard Worker 
425*d83cc019SAndroid Build Coastguard Worker 	close(fd);
426*d83cc019SAndroid Build Coastguard Worker }
427*d83cc019SAndroid Build Coastguard Worker 
428*d83cc019SAndroid Build Coastguard Worker igt_main
429*d83cc019SAndroid Build Coastguard Worker {
430*d83cc019SAndroid Build Coastguard Worker 	uint32_t handle;
431*d83cc019SAndroid Build Coastguard Worker 	int fd;
432*d83cc019SAndroid Build Coastguard Worker 
433*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
434*d83cc019SAndroid Build Coastguard Worker 		fd = drm_open_driver(DRIVER_INTEL);
435*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(fd);
436*d83cc019SAndroid Build Coastguard Worker 
437*d83cc019SAndroid Build Coastguard Worker 		parser_version = command_parser_version(fd);
438*d83cc019SAndroid Build Coastguard Worker 		igt_require(parser_version != -1);
439*d83cc019SAndroid Build Coastguard Worker 
440*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_uses_ppgtt(fd));
441*d83cc019SAndroid Build Coastguard Worker 
442*d83cc019SAndroid Build Coastguard Worker 		handle = gem_create(fd, 4096);
443*d83cc019SAndroid Build Coastguard Worker 
444*d83cc019SAndroid Build Coastguard Worker 		/* ATM cmd parser only exists on gen7. */
445*d83cc019SAndroid Build Coastguard Worker 		igt_require(intel_gen(intel_get_drm_devid(fd)) == 7);
446*d83cc019SAndroid Build Coastguard Worker 		igt_fork_hang_detector(fd);
447*d83cc019SAndroid Build Coastguard Worker 	}
448*d83cc019SAndroid Build Coastguard Worker 
449*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("basic-allowed") {
450*d83cc019SAndroid Build Coastguard Worker 		uint32_t pc[] = {
451*d83cc019SAndroid Build Coastguard Worker 			GFX_OP_PIPE_CONTROL,
452*d83cc019SAndroid Build Coastguard Worker 			PIPE_CONTROL_QW_WRITE,
453*d83cc019SAndroid Build Coastguard Worker 			0, /* To be patched */
454*d83cc019SAndroid Build Coastguard Worker 			0x12000000,
455*d83cc019SAndroid Build Coastguard Worker 			0,
456*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
457*d83cc019SAndroid Build Coastguard Worker 		};
458*d83cc019SAndroid Build Coastguard Worker 		exec_batch_patched(fd, handle,
459*d83cc019SAndroid Build Coastguard Worker 				   pc, sizeof(pc),
460*d83cc019SAndroid Build Coastguard Worker 				   8, /* patch offset, */
461*d83cc019SAndroid Build Coastguard Worker 				   0x12000000);
462*d83cc019SAndroid Build Coastguard Worker 	}
463*d83cc019SAndroid Build Coastguard Worker 
464*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("basic-rejected") {
465*d83cc019SAndroid Build Coastguard Worker 		uint32_t invalid_cmd[] = {
466*d83cc019SAndroid Build Coastguard Worker 			INSTR_INVALID_CLIENT << INSTR_CLIENT_SHIFT,
467*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
468*d83cc019SAndroid Build Coastguard Worker 		};
469*d83cc019SAndroid Build Coastguard Worker 		uint32_t invalid_set_context[] = {
470*d83cc019SAndroid Build Coastguard Worker 			MI_SET_CONTEXT | 32, /* invalid length */
471*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
472*d83cc019SAndroid Build Coastguard Worker 		};
473*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle,
474*d83cc019SAndroid Build Coastguard Worker 			   invalid_cmd, sizeof(invalid_cmd),
475*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
476*d83cc019SAndroid Build Coastguard Worker 			   -EINVAL);
477*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle,
478*d83cc019SAndroid Build Coastguard Worker 			   invalid_cmd, sizeof(invalid_cmd),
479*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_BSD,
480*d83cc019SAndroid Build Coastguard Worker 			   -EINVAL);
481*d83cc019SAndroid Build Coastguard Worker 		if (gem_has_blt(fd)) {
482*d83cc019SAndroid Build Coastguard Worker 			exec_batch(fd, handle,
483*d83cc019SAndroid Build Coastguard Worker 				   invalid_cmd, sizeof(invalid_cmd),
484*d83cc019SAndroid Build Coastguard Worker 				   I915_EXEC_BLT,
485*d83cc019SAndroid Build Coastguard Worker 				   -EINVAL);
486*d83cc019SAndroid Build Coastguard Worker 		}
487*d83cc019SAndroid Build Coastguard Worker 		if (gem_has_vebox(fd)) {
488*d83cc019SAndroid Build Coastguard Worker 			exec_batch(fd, handle,
489*d83cc019SAndroid Build Coastguard Worker 				   invalid_cmd, sizeof(invalid_cmd),
490*d83cc019SAndroid Build Coastguard Worker 				   I915_EXEC_VEBOX,
491*d83cc019SAndroid Build Coastguard Worker 				   -EINVAL);
492*d83cc019SAndroid Build Coastguard Worker 		}
493*d83cc019SAndroid Build Coastguard Worker 
494*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle,
495*d83cc019SAndroid Build Coastguard Worker 			   invalid_set_context, sizeof(invalid_set_context),
496*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
497*d83cc019SAndroid Build Coastguard Worker 			   -EINVAL);
498*d83cc019SAndroid Build Coastguard Worker 	}
499*d83cc019SAndroid Build Coastguard Worker 
500*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("basic-allocation") {
501*d83cc019SAndroid Build Coastguard Worker 		test_allocations(fd);
502*d83cc019SAndroid Build Coastguard Worker 	}
503*d83cc019SAndroid Build Coastguard Worker 
504*d83cc019SAndroid Build Coastguard Worker 	igt_subtest_group {
505*d83cc019SAndroid Build Coastguard Worker #define REG(R, MSK, INI, V, OK, MIN_V) { #R, R, MSK, INI, V, OK, MIN_V }
506*d83cc019SAndroid Build Coastguard Worker 		struct test_lri lris[] = {
507*d83cc019SAndroid Build Coastguard Worker 			/* dummy head pointer */
508*d83cc019SAndroid Build Coastguard Worker 			REG(OASTATUS2,
509*d83cc019SAndroid Build Coastguard Worker 			    0xffffff80, 0xdeadf000, 0xbeeff000, false, 0),
510*d83cc019SAndroid Build Coastguard Worker 			/* NB: [1:0] MBZ */
511*d83cc019SAndroid Build Coastguard Worker 			REG(SO_WRITE_OFFSET_0,
512*d83cc019SAndroid Build Coastguard Worker 			    0xfffffffc, 0xabcdabc0, 0xbeefbee0, true, 0),
513*d83cc019SAndroid Build Coastguard Worker 
514*d83cc019SAndroid Build Coastguard Worker 			/* It's really important for us to check that
515*d83cc019SAndroid Build Coastguard Worker 			 * an LRI to OACONTROL doesn't result in an
516*d83cc019SAndroid Build Coastguard Worker 			 * EINVAL error because Mesa attempts writing
517*d83cc019SAndroid Build Coastguard Worker 			 * to OACONTROL to determine what extensions to
518*d83cc019SAndroid Build Coastguard Worker 			 * expose and will abort() for execbuffer()
519*d83cc019SAndroid Build Coastguard Worker 			 * errors.
520*d83cc019SAndroid Build Coastguard Worker 			 *
521*d83cc019SAndroid Build Coastguard Worker 			 * Mesa can gracefully recognise and handle the
522*d83cc019SAndroid Build Coastguard Worker 			 * LRI becoming a NOOP.
523*d83cc019SAndroid Build Coastguard Worker 			 *
524*d83cc019SAndroid Build Coastguard Worker 			 * The test values represent dummy context IDs
525*d83cc019SAndroid Build Coastguard Worker 			 * while leaving the OA unit disabled
526*d83cc019SAndroid Build Coastguard Worker 			 */
527*d83cc019SAndroid Build Coastguard Worker 			REG(OACONTROL,
528*d83cc019SAndroid Build Coastguard Worker 			    0xfffff000, 0xfeed0000, 0x31337000, false, 9)
529*d83cc019SAndroid Build Coastguard Worker 		};
530*d83cc019SAndroid Build Coastguard Worker #undef REG
531*d83cc019SAndroid Build Coastguard Worker 
532*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
533*d83cc019SAndroid Build Coastguard Worker 			intel_register_access_init(intel_get_pci_device(), 0, fd);
534*d83cc019SAndroid Build Coastguard Worker 		}
535*d83cc019SAndroid Build Coastguard Worker 
536*d83cc019SAndroid Build Coastguard Worker 		for (int i = 0; i < ARRAY_SIZE(lris); i++) {
537*d83cc019SAndroid Build Coastguard Worker 			igt_subtest_f("test-lri-%s", lris[i].name) {
538*d83cc019SAndroid Build Coastguard Worker 				igt_require_f(parser_version >= lris[i].min_ver,
539*d83cc019SAndroid Build Coastguard Worker 					      "minimum required parser version for test = %d\n",
540*d83cc019SAndroid Build Coastguard Worker 					      lris[i].min_ver);
541*d83cc019SAndroid Build Coastguard Worker 				test_lri(fd, handle, lris + i);
542*d83cc019SAndroid Build Coastguard Worker 			}
543*d83cc019SAndroid Build Coastguard Worker 		}
544*d83cc019SAndroid Build Coastguard Worker 
545*d83cc019SAndroid Build Coastguard Worker 		igt_fixture {
546*d83cc019SAndroid Build Coastguard Worker 			intel_register_access_fini();
547*d83cc019SAndroid Build Coastguard Worker 		}
548*d83cc019SAndroid Build Coastguard Worker 	}
549*d83cc019SAndroid Build Coastguard Worker 
550*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("bitmasks") {
551*d83cc019SAndroid Build Coastguard Worker 		uint32_t pc[] = {
552*d83cc019SAndroid Build Coastguard Worker 			GFX_OP_PIPE_CONTROL,
553*d83cc019SAndroid Build Coastguard Worker 			(PIPE_CONTROL_QW_WRITE |
554*d83cc019SAndroid Build Coastguard Worker 			 PIPE_CONTROL_LRI_POST_OP),
555*d83cc019SAndroid Build Coastguard Worker 			0, /* To be patched */
556*d83cc019SAndroid Build Coastguard Worker 			0x12000000,
557*d83cc019SAndroid Build Coastguard Worker 			0,
558*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
559*d83cc019SAndroid Build Coastguard Worker 		};
560*d83cc019SAndroid Build Coastguard Worker 		if (parser_version >= 8) {
561*d83cc019SAndroid Build Coastguard Worker 			/* Expect to read back zero since the command should be
562*d83cc019SAndroid Build Coastguard Worker 			 * squashed to a NOOP
563*d83cc019SAndroid Build Coastguard Worker 			 */
564*d83cc019SAndroid Build Coastguard Worker 			exec_batch_patched(fd, handle,
565*d83cc019SAndroid Build Coastguard Worker 					   pc, sizeof(pc),
566*d83cc019SAndroid Build Coastguard Worker 					   8, /* patch offset, */
567*d83cc019SAndroid Build Coastguard Worker 					   0x0);
568*d83cc019SAndroid Build Coastguard Worker 		} else {
569*d83cc019SAndroid Build Coastguard Worker 			exec_batch(fd, handle,
570*d83cc019SAndroid Build Coastguard Worker 				   pc, sizeof(pc),
571*d83cc019SAndroid Build Coastguard Worker 				   I915_EXEC_RENDER,
572*d83cc019SAndroid Build Coastguard Worker 				   -EINVAL);
573*d83cc019SAndroid Build Coastguard Worker 		}
574*d83cc019SAndroid Build Coastguard Worker 	}
575*d83cc019SAndroid Build Coastguard Worker 
576*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("batch-without-end") {
577*d83cc019SAndroid Build Coastguard Worker 		uint32_t noop[1024] = { 0 };
578*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle,
579*d83cc019SAndroid Build Coastguard Worker 			   noop, sizeof(noop),
580*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
581*d83cc019SAndroid Build Coastguard Worker 			   -EINVAL);
582*d83cc019SAndroid Build Coastguard Worker 	}
583*d83cc019SAndroid Build Coastguard Worker 
584*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("cmd-crossing-page") {
585*d83cc019SAndroid Build Coastguard Worker 		uint32_t lri_ok[] = {
586*d83cc019SAndroid Build Coastguard Worker 			MI_LOAD_REGISTER_IMM,
587*d83cc019SAndroid Build Coastguard Worker 			SO_WRITE_OFFSET_0, /* allowed register address */
588*d83cc019SAndroid Build Coastguard Worker 			0xdcbaabc0, /* [1:0] MBZ */
589*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
590*d83cc019SAndroid Build Coastguard Worker 		};
591*d83cc019SAndroid Build Coastguard Worker 		uint32_t store_reg[] = {
592*d83cc019SAndroid Build Coastguard Worker 			MI_STORE_REGISTER_MEM | (3 - 2),
593*d83cc019SAndroid Build Coastguard Worker 			SO_WRITE_OFFSET_0,
594*d83cc019SAndroid Build Coastguard Worker 			0, /* reloc */
595*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
596*d83cc019SAndroid Build Coastguard Worker 		};
597*d83cc019SAndroid Build Coastguard Worker 		exec_split_batch(fd,
598*d83cc019SAndroid Build Coastguard Worker 				 lri_ok, sizeof(lri_ok),
599*d83cc019SAndroid Build Coastguard Worker 				 I915_EXEC_RENDER,
600*d83cc019SAndroid Build Coastguard Worker 				 0);
601*d83cc019SAndroid Build Coastguard Worker 		exec_batch_patched(fd, handle,
602*d83cc019SAndroid Build Coastguard Worker 				   store_reg,
603*d83cc019SAndroid Build Coastguard Worker 				   sizeof(store_reg),
604*d83cc019SAndroid Build Coastguard Worker 				   2 * sizeof(uint32_t), /* reloc */
605*d83cc019SAndroid Build Coastguard Worker 				   0xdcbaabc0);
606*d83cc019SAndroid Build Coastguard Worker 	}
607*d83cc019SAndroid Build Coastguard Worker 
608*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("oacontrol-tracking") {
609*d83cc019SAndroid Build Coastguard Worker 		uint32_t lri_ok[] = {
610*d83cc019SAndroid Build Coastguard Worker 			MI_LOAD_REGISTER_IMM,
611*d83cc019SAndroid Build Coastguard Worker 			OACONTROL,
612*d83cc019SAndroid Build Coastguard Worker 			0x31337000,
613*d83cc019SAndroid Build Coastguard Worker 			MI_LOAD_REGISTER_IMM,
614*d83cc019SAndroid Build Coastguard Worker 			OACONTROL,
615*d83cc019SAndroid Build Coastguard Worker 			0x0,
616*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
617*d83cc019SAndroid Build Coastguard Worker 			0
618*d83cc019SAndroid Build Coastguard Worker 		};
619*d83cc019SAndroid Build Coastguard Worker 		uint32_t lri_bad[] = {
620*d83cc019SAndroid Build Coastguard Worker 			MI_LOAD_REGISTER_IMM,
621*d83cc019SAndroid Build Coastguard Worker 			OACONTROL,
622*d83cc019SAndroid Build Coastguard Worker 			0x31337000,
623*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
624*d83cc019SAndroid Build Coastguard Worker 		};
625*d83cc019SAndroid Build Coastguard Worker 		uint32_t lri_extra_bad[] = {
626*d83cc019SAndroid Build Coastguard Worker 			MI_LOAD_REGISTER_IMM,
627*d83cc019SAndroid Build Coastguard Worker 			OACONTROL,
628*d83cc019SAndroid Build Coastguard Worker 			0x31337000,
629*d83cc019SAndroid Build Coastguard Worker 			MI_LOAD_REGISTER_IMM,
630*d83cc019SAndroid Build Coastguard Worker 			OACONTROL,
631*d83cc019SAndroid Build Coastguard Worker 			0x0,
632*d83cc019SAndroid Build Coastguard Worker 			MI_LOAD_REGISTER_IMM,
633*d83cc019SAndroid Build Coastguard Worker 			OACONTROL,
634*d83cc019SAndroid Build Coastguard Worker 			0x31337000,
635*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
636*d83cc019SAndroid Build Coastguard Worker 		};
637*d83cc019SAndroid Build Coastguard Worker 
638*d83cc019SAndroid Build Coastguard Worker 		igt_require(parser_version < 9);
639*d83cc019SAndroid Build Coastguard Worker 
640*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle,
641*d83cc019SAndroid Build Coastguard Worker 			   lri_ok, sizeof(lri_ok),
642*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
643*d83cc019SAndroid Build Coastguard Worker 			   0);
644*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle,
645*d83cc019SAndroid Build Coastguard Worker 			   lri_bad, sizeof(lri_bad),
646*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
647*d83cc019SAndroid Build Coastguard Worker 			   -EINVAL);
648*d83cc019SAndroid Build Coastguard Worker 		exec_batch(fd, handle,
649*d83cc019SAndroid Build Coastguard Worker 			   lri_extra_bad, sizeof(lri_extra_bad),
650*d83cc019SAndroid Build Coastguard Worker 			   I915_EXEC_RENDER,
651*d83cc019SAndroid Build Coastguard Worker 			   -EINVAL);
652*d83cc019SAndroid Build Coastguard Worker 	}
653*d83cc019SAndroid Build Coastguard Worker 
654*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("chained-batch") {
655*d83cc019SAndroid Build Coastguard Worker 		uint32_t pc[] = {
656*d83cc019SAndroid Build Coastguard Worker 			GFX_OP_PIPE_CONTROL,
657*d83cc019SAndroid Build Coastguard Worker 			PIPE_CONTROL_QW_WRITE,
658*d83cc019SAndroid Build Coastguard Worker 			0, /* To be patched */
659*d83cc019SAndroid Build Coastguard Worker 			0x12000000,
660*d83cc019SAndroid Build Coastguard Worker 			0,
661*d83cc019SAndroid Build Coastguard Worker 			MI_BATCH_BUFFER_END,
662*d83cc019SAndroid Build Coastguard Worker 		};
663*d83cc019SAndroid Build Coastguard Worker 		exec_batch_chained(fd, handle,
664*d83cc019SAndroid Build Coastguard Worker 				   pc, sizeof(pc),
665*d83cc019SAndroid Build Coastguard Worker 				   8, /* patch offset, */
666*d83cc019SAndroid Build Coastguard Worker 				   0x12000000);
667*d83cc019SAndroid Build Coastguard Worker 	}
668*d83cc019SAndroid Build Coastguard Worker 
669*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("load-register-reg")
670*d83cc019SAndroid Build Coastguard Worker 		hsw_load_register_reg();
671*d83cc019SAndroid Build Coastguard Worker 
672*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
673*d83cc019SAndroid Build Coastguard Worker 		igt_stop_hang_detector();
674*d83cc019SAndroid Build Coastguard Worker 		gem_close(fd, handle);
675*d83cc019SAndroid Build Coastguard Worker 
676*d83cc019SAndroid Build Coastguard Worker 		close(fd);
677*d83cc019SAndroid Build Coastguard Worker 	}
678*d83cc019SAndroid Build Coastguard Worker }
679