Use SIGTERM in replace of SIGQUIT
[platform/upstream/intel-gpu-tools.git] / lib / drmtest.c
1 /*
2  * Copyright © 2007, 2011, 2013 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Eric Anholt <eric@anholt.net>
25  *    Daniel Vetter <daniel.vetter@ffwll.ch>
26  *
27  */
28
29 #ifndef ANDROID
30 #define _GNU_SOURCE
31 #else
32 #include <libgen.h>
33 #endif
34 #include <stdio.h>
35 #include <fcntl.h>
36 #include <sys/stat.h>
37 #include <sys/ioctl.h>
38 #include <string.h>
39 #include <sys/mman.h>
40 #include <signal.h>
41 #include <pciaccess.h>
42 #include <getopt.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <sys/wait.h>
46 #include <sys/types.h>
47 #include <sys/syscall.h>
48 #include <sys/utsname.h>
49 #include <termios.h>
50
51 #include "drmtest.h"
52 #include "i915_drm.h"
53 #include "intel_chipset.h"
54 #include "intel_io.h"
55 #include "igt_debugfs.h"
56 #include "version.h"
57 #include "config.h"
58 #include "intel_reg.h"
59 #include "ioctl_wrappers.h"
60
61 /**
62  * SECTION:drmtest
63  * @short_description: Base library for drm tests and tools
64  * @title: drmtest
65  * @include: drmtest.h
66  *
67  * This library contains the basic support for writing tests, with the most
68  * important part being the helper function to open drm device nodes.
69  *
70  * But there's also a bit of other assorted stuff here.
71  *
72  * Note that this library's header pulls in the [i-g-t core](intel-gpu-tools-i-g-t-core.html)
73  * and [batchbuffer](intel-gpu-tools-intel-batchbuffer.html) libraries as dependencies.
74  */
75
76 static int
77 is_intel(int fd)
78 {
79         struct drm_i915_getparam gp;
80         int devid;
81
82         gp.param = I915_PARAM_CHIPSET_ID;
83         gp.value = &devid;
84
85         if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp)))
86                 return 0;
87
88         return IS_INTEL(devid);
89 }
90
91 static void check_stop_rings(void)
92 {
93         enum stop_ring_flags flags;
94         flags = igt_get_stop_rings();
95         igt_warn_on_f(flags != 0,
96                       "i915_ring_stop flags on exit 0x%x, can't quiescent gpu cleanly\n",
97                       flags);
98
99         if (flags)
100                 igt_set_stop_rings(STOP_RING_NONE);
101 }
102
103 #define LOCAL_I915_EXEC_VEBOX   (4 << 0)
104 /**
105  * gem_quiescent_gpu:
106  * @fd: open i915 drm file descriptor
107  *
108  * Ensure the gpu is idle by launching a nop execbuf and stalling for it. This
109  * is automatically run when opening a drm device node and is also installed as
110  * an exit handler to have the best assurance that the test is run in a pristine
111  * and controlled environment.
112  *
113  * This function simply allows tests to make additional calls in-between, if so
114  * desired.
115  */
116 void gem_quiescent_gpu(int fd)
117 {
118         uint32_t batch[2] = {MI_BATCH_BUFFER_END, 0};
119         uint32_t handle;
120         struct drm_i915_gem_execbuffer2 execbuf;
121         struct drm_i915_gem_exec_object2 gem_exec[1];
122
123         check_stop_rings();
124
125         handle = gem_create(fd, 4096);
126         gem_write(fd, handle, 0, batch, sizeof(batch));
127
128         gem_exec[0].handle = handle;
129         gem_exec[0].relocation_count = 0;
130         gem_exec[0].relocs_ptr = 0;
131         gem_exec[0].alignment = 0;
132         gem_exec[0].offset = 0;
133         gem_exec[0].flags = 0;
134         gem_exec[0].rsvd1 = 0;
135         gem_exec[0].rsvd2 = 0;
136
137         execbuf.buffers_ptr = (uintptr_t)gem_exec;
138         execbuf.buffer_count = 1;
139         execbuf.batch_start_offset = 0;
140         execbuf.batch_len = 8;
141         execbuf.cliprects_ptr = 0;
142         execbuf.num_cliprects = 0;
143         execbuf.DR1 = 0;
144         execbuf.DR4 = 0;
145         execbuf.flags = 0;
146         i915_execbuffer2_set_context_id(execbuf, 0);
147         execbuf.rsvd2 = 0;
148
149         do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
150
151         if (gem_has_blt(fd)) {
152                 execbuf.flags = I915_EXEC_BLT;
153                 do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
154         }
155
156         if (gem_has_bsd(fd)) {
157                 execbuf.flags = I915_EXEC_BSD;
158                 do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
159         }
160
161         if (gem_has_vebox(fd)) {
162                 execbuf.flags = LOCAL_I915_EXEC_VEBOX;
163                 do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
164         }
165
166         gem_sync(fd, handle);
167         igt_drop_caches_set(DROP_RETIRE);
168         gem_close(fd, handle);
169 }
170
171 /**
172  * drm_get_card:
173  *
174  * Get an i915 drm card index number for use in /dev or /sys. The minor index of
175  * the legacy node is returned, not of the control or render node.
176  *
177  * Returns:
178  * The i915 drm index or -1 on error
179  */
180 int drm_get_card(void)
181 {
182         char *name;
183         int i, fd;
184
185         for (i = 0; i < 16; i++) {
186                 int ret;
187
188                 ret = asprintf(&name, "/dev/dri/card%u", i);
189                 igt_assert(ret != -1);
190
191                 fd = open(name, O_RDWR);
192                 free(name);
193
194                 if (fd == -1)
195                         continue;
196
197                 if (!is_intel(fd)) {
198                         close(fd);
199                         continue;
200                 }
201
202                 close(fd);
203                 return i;
204         }
205
206         igt_skip("No intel gpu found\n");
207
208         return -1;
209 }
210
211 /** Open the first DRM device we can find, searching up to 16 device nodes */
212 static int __drm_open_any(void)
213 {
214         char *name;
215         int ret, fd;
216
217         ret = asprintf(&name, "/dev/dri/card%d", drm_get_card());
218         if (ret == -1)
219                 return -1;
220
221         fd = open(name, O_RDWR);
222         free(name);
223
224         if (!is_intel(fd)) {
225                 close(fd);
226                 fd = -1;
227         }
228
229         return fd;
230 }
231
232 static int __drm_open_any_render(void)
233 {
234         char *name;
235         int i, fd;
236
237         for (i = 128; i < (128 + 16); i++) {
238                 int ret;
239
240                 ret = asprintf(&name, "/dev/dri/renderD%u", i);
241                 igt_assert(ret != -1);
242
243                 fd = open(name, O_RDWR);
244                 free(name);
245
246                 if (fd == -1)
247                         continue;
248
249                 if (!is_intel(fd)) {
250                         close(fd);
251                         fd = -1;
252                         continue;
253                 }
254
255                 return fd;
256         }
257
258         return fd;
259 }
260
261 static int at_exit_drm_fd = -1;
262 static int at_exit_drm_render_fd = -1;
263
264 static void quiescent_gpu_at_exit(int sig)
265 {
266         if (at_exit_drm_fd < 0)
267                 return;
268
269         check_stop_rings();
270         gem_quiescent_gpu(at_exit_drm_fd);
271         close(at_exit_drm_fd);
272         at_exit_drm_fd = -1;
273 }
274
275 static void quiescent_gpu_at_exit_render(int sig)
276 {
277         if (at_exit_drm_render_fd < 0)
278                 return;
279
280         check_stop_rings();
281         gem_quiescent_gpu(at_exit_drm_render_fd);
282         close(at_exit_drm_render_fd);
283         at_exit_drm_render_fd = -1;
284 }
285
286 /**
287  * drm_open_any:
288  *
289  * Open an i915 drm legacy device node.
290  *
291  * Returns:
292  * The i915 drm file descriptor or -1 on error
293  */
294 int drm_open_any(void)
295 {
296         static int open_count;
297         int fd = __drm_open_any();
298
299         igt_require(fd >= 0);
300
301         if (__sync_fetch_and_add(&open_count, 1))
302                 return fd;
303
304         gem_quiescent_gpu(fd);
305         at_exit_drm_fd = __drm_open_any();
306         igt_install_exit_handler(quiescent_gpu_at_exit);
307
308         return fd;
309 }
310
311 /**
312  * drm_open_any:
313  *
314  * Open an i915 drm render device node.
315  *
316  * Returns:
317  * The i915 drm file descriptor or -1 on error
318  */
319 int drm_open_any_render(void)
320 {
321         static int open_count;
322         int fd = __drm_open_any_render();
323
324         /* no render nodes, fallback to drm_open_any() */
325         if (fd == -1)
326                 return drm_open_any();
327
328         if (__sync_fetch_and_add(&open_count, 1))
329                 return fd;
330
331         at_exit_drm_render_fd = __drm_open_any();
332         gem_quiescent_gpu(fd);
333         igt_install_exit_handler(quiescent_gpu_at_exit_render);
334
335         return fd;
336 }