1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker *
4*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker *
11*d83cc019SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker * Software.
14*d83cc019SAndroid Build Coastguard Worker *
15*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker */
23*d83cc019SAndroid Build Coastguard Worker
24*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
25*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
26*d83cc019SAndroid Build Coastguard Worker #include <string.h>
27*d83cc019SAndroid Build Coastguard Worker #include <stdint.h>
28*d83cc019SAndroid Build Coastguard Worker #include <stdbool.h>
29*d83cc019SAndroid Build Coastguard Worker #include <stdarg.h>
30*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
31*d83cc019SAndroid Build Coastguard Worker #include <sys/types.h>
32*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
33*d83cc019SAndroid Build Coastguard Worker #include <sys/ioctl.h>
34*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
35*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
36*d83cc019SAndroid Build Coastguard Worker #include <sys/mman.h>
37*d83cc019SAndroid Build Coastguard Worker #include <dlfcn.h>
38*d83cc019SAndroid Build Coastguard Worker #include <i915_drm.h>
39*d83cc019SAndroid Build Coastguard Worker #include <pthread.h>
40*d83cc019SAndroid Build Coastguard Worker
41*d83cc019SAndroid Build Coastguard Worker #include "intel_aub.h"
42*d83cc019SAndroid Build Coastguard Worker #include "intel_chipset.h"
43*d83cc019SAndroid Build Coastguard Worker
44*d83cc019SAndroid Build Coastguard Worker static int (*libc_close)(int fd);
45*d83cc019SAndroid Build Coastguard Worker static int (*libc_ioctl)(int fd, unsigned long request, void *argp);
46*d83cc019SAndroid Build Coastguard Worker
47*d83cc019SAndroid Build Coastguard Worker static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
48*d83cc019SAndroid Build Coastguard Worker
49*d83cc019SAndroid Build Coastguard Worker struct trace {
50*d83cc019SAndroid Build Coastguard Worker int fd;
51*d83cc019SAndroid Build Coastguard Worker FILE *file;
52*d83cc019SAndroid Build Coastguard Worker struct trace *next;
53*d83cc019SAndroid Build Coastguard Worker } *traces;
54*d83cc019SAndroid Build Coastguard Worker
55*d83cc019SAndroid Build Coastguard Worker #define DRM_MAJOR 226
56*d83cc019SAndroid Build Coastguard Worker
57*d83cc019SAndroid Build Coastguard Worker enum {
58*d83cc019SAndroid Build Coastguard Worker ADD_BO = 0,
59*d83cc019SAndroid Build Coastguard Worker DEL_BO,
60*d83cc019SAndroid Build Coastguard Worker ADD_CTX,
61*d83cc019SAndroid Build Coastguard Worker DEL_CTX,
62*d83cc019SAndroid Build Coastguard Worker EXEC,
63*d83cc019SAndroid Build Coastguard Worker WAIT,
64*d83cc019SAndroid Build Coastguard Worker };
65*d83cc019SAndroid Build Coastguard Worker
66*d83cc019SAndroid Build Coastguard Worker static struct trace_verion {
67*d83cc019SAndroid Build Coastguard Worker uint32_t magic;
68*d83cc019SAndroid Build Coastguard Worker uint32_t version;
69*d83cc019SAndroid Build Coastguard Worker } version = {
70*d83cc019SAndroid Build Coastguard Worker .magic = 0xdeadbeef,
71*d83cc019SAndroid Build Coastguard Worker .version = 1
72*d83cc019SAndroid Build Coastguard Worker };
73*d83cc019SAndroid Build Coastguard Worker
74*d83cc019SAndroid Build Coastguard Worker struct trace_add_bo {
75*d83cc019SAndroid Build Coastguard Worker uint8_t cmd;
76*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
77*d83cc019SAndroid Build Coastguard Worker uint64_t size;
78*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
79*d83cc019SAndroid Build Coastguard Worker struct trace_del_bo {
80*d83cc019SAndroid Build Coastguard Worker uint8_t cmd;
81*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
82*d83cc019SAndroid Build Coastguard Worker }__attribute__((packed));
83*d83cc019SAndroid Build Coastguard Worker
84*d83cc019SAndroid Build Coastguard Worker struct trace_add_ctx {
85*d83cc019SAndroid Build Coastguard Worker uint8_t cmd;
86*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
87*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
88*d83cc019SAndroid Build Coastguard Worker struct trace_del_ctx {
89*d83cc019SAndroid Build Coastguard Worker uint8_t cmd;
90*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
91*d83cc019SAndroid Build Coastguard Worker }__attribute__((packed));
92*d83cc019SAndroid Build Coastguard Worker
93*d83cc019SAndroid Build Coastguard Worker struct trace_exec {
94*d83cc019SAndroid Build Coastguard Worker uint8_t cmd;
95*d83cc019SAndroid Build Coastguard Worker uint32_t object_count;
96*d83cc019SAndroid Build Coastguard Worker uint64_t flags;
97*d83cc019SAndroid Build Coastguard Worker uint32_t context;
98*d83cc019SAndroid Build Coastguard Worker }__attribute__((packed));
99*d83cc019SAndroid Build Coastguard Worker
100*d83cc019SAndroid Build Coastguard Worker struct trace_exec_object {
101*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
102*d83cc019SAndroid Build Coastguard Worker uint32_t relocation_count;
103*d83cc019SAndroid Build Coastguard Worker uint64_t alignment;
104*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
105*d83cc019SAndroid Build Coastguard Worker uint64_t flags;
106*d83cc019SAndroid Build Coastguard Worker uint64_t rsvd1;
107*d83cc019SAndroid Build Coastguard Worker uint64_t rsvd2;
108*d83cc019SAndroid Build Coastguard Worker }__attribute__((packed));
109*d83cc019SAndroid Build Coastguard Worker
110*d83cc019SAndroid Build Coastguard Worker struct trace_exec_relocation {
111*d83cc019SAndroid Build Coastguard Worker uint32_t target_handle;
112*d83cc019SAndroid Build Coastguard Worker uint32_t delta;
113*d83cc019SAndroid Build Coastguard Worker uint64_t offset;
114*d83cc019SAndroid Build Coastguard Worker uint64_t presumed_offset;
115*d83cc019SAndroid Build Coastguard Worker uint32_t read_domains;
116*d83cc019SAndroid Build Coastguard Worker uint32_t write_domain;
117*d83cc019SAndroid Build Coastguard Worker }__attribute__((packed));
118*d83cc019SAndroid Build Coastguard Worker
119*d83cc019SAndroid Build Coastguard Worker struct trace_wait {
120*d83cc019SAndroid Build Coastguard Worker uint8_t cmd;
121*d83cc019SAndroid Build Coastguard Worker uint32_t handle;
122*d83cc019SAndroid Build Coastguard Worker } __attribute__((packed));
123*d83cc019SAndroid Build Coastguard Worker
124*d83cc019SAndroid Build Coastguard Worker static void __attribute__ ((format(__printf__, 2, 3)))
fail_if(int cond,const char * format,...)125*d83cc019SAndroid Build Coastguard Worker fail_if(int cond, const char *format, ...)
126*d83cc019SAndroid Build Coastguard Worker {
127*d83cc019SAndroid Build Coastguard Worker va_list args;
128*d83cc019SAndroid Build Coastguard Worker
129*d83cc019SAndroid Build Coastguard Worker if (!cond)
130*d83cc019SAndroid Build Coastguard Worker return;
131*d83cc019SAndroid Build Coastguard Worker
132*d83cc019SAndroid Build Coastguard Worker va_start(args, format);
133*d83cc019SAndroid Build Coastguard Worker vfprintf(stderr, format, args);
134*d83cc019SAndroid Build Coastguard Worker va_end(args);
135*d83cc019SAndroid Build Coastguard Worker
136*d83cc019SAndroid Build Coastguard Worker abort();
137*d83cc019SAndroid Build Coastguard Worker }
138*d83cc019SAndroid Build Coastguard Worker
139*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_FENCE_IN (1<<16)
140*d83cc019SAndroid Build Coastguard Worker #define LOCAL_I915_EXEC_FENCE_OUT (1<<17)
141*d83cc019SAndroid Build Coastguard Worker
142*d83cc019SAndroid Build Coastguard Worker static void
trace_exec(struct trace * trace,const struct drm_i915_gem_execbuffer2 * execbuffer2)143*d83cc019SAndroid Build Coastguard Worker trace_exec(struct trace *trace,
144*d83cc019SAndroid Build Coastguard Worker const struct drm_i915_gem_execbuffer2 *execbuffer2)
145*d83cc019SAndroid Build Coastguard Worker {
146*d83cc019SAndroid Build Coastguard Worker #define to_ptr(T, x) ((T *)(uintptr_t)(x))
147*d83cc019SAndroid Build Coastguard Worker const struct drm_i915_gem_exec_object2 *exec_objects =
148*d83cc019SAndroid Build Coastguard Worker to_ptr(typeof(*exec_objects), execbuffer2->buffers_ptr);
149*d83cc019SAndroid Build Coastguard Worker
150*d83cc019SAndroid Build Coastguard Worker fail_if(execbuffer2->flags & (LOCAL_I915_EXEC_FENCE_IN | LOCAL_I915_EXEC_FENCE_OUT),
151*d83cc019SAndroid Build Coastguard Worker "fences not supported yet\n");
152*d83cc019SAndroid Build Coastguard Worker
153*d83cc019SAndroid Build Coastguard Worker flockfile(trace->file);
154*d83cc019SAndroid Build Coastguard Worker {
155*d83cc019SAndroid Build Coastguard Worker struct trace_exec t = {
156*d83cc019SAndroid Build Coastguard Worker EXEC,
157*d83cc019SAndroid Build Coastguard Worker execbuffer2->buffer_count,
158*d83cc019SAndroid Build Coastguard Worker execbuffer2->flags,
159*d83cc019SAndroid Build Coastguard Worker execbuffer2->rsvd1,
160*d83cc019SAndroid Build Coastguard Worker };
161*d83cc019SAndroid Build Coastguard Worker fwrite(&t, sizeof(t), 1, trace->file);
162*d83cc019SAndroid Build Coastguard Worker }
163*d83cc019SAndroid Build Coastguard Worker
164*d83cc019SAndroid Build Coastguard Worker for (uint32_t i = 0; i < execbuffer2->buffer_count; i++) {
165*d83cc019SAndroid Build Coastguard Worker const struct drm_i915_gem_exec_object2 *obj = &exec_objects[i];
166*d83cc019SAndroid Build Coastguard Worker const struct drm_i915_gem_relocation_entry *relocs =
167*d83cc019SAndroid Build Coastguard Worker to_ptr(typeof(*relocs), obj->relocs_ptr);
168*d83cc019SAndroid Build Coastguard Worker {
169*d83cc019SAndroid Build Coastguard Worker struct trace_exec_object t = {
170*d83cc019SAndroid Build Coastguard Worker obj->handle,
171*d83cc019SAndroid Build Coastguard Worker obj->relocation_count,
172*d83cc019SAndroid Build Coastguard Worker obj->alignment,
173*d83cc019SAndroid Build Coastguard Worker obj->offset,
174*d83cc019SAndroid Build Coastguard Worker obj->flags,
175*d83cc019SAndroid Build Coastguard Worker obj->rsvd1,
176*d83cc019SAndroid Build Coastguard Worker obj->rsvd2
177*d83cc019SAndroid Build Coastguard Worker };
178*d83cc019SAndroid Build Coastguard Worker fwrite(&t, sizeof(t), 1, trace->file);
179*d83cc019SAndroid Build Coastguard Worker }
180*d83cc019SAndroid Build Coastguard Worker fwrite(relocs, sizeof(*relocs), obj->relocation_count,
181*d83cc019SAndroid Build Coastguard Worker trace->file);
182*d83cc019SAndroid Build Coastguard Worker }
183*d83cc019SAndroid Build Coastguard Worker
184*d83cc019SAndroid Build Coastguard Worker fflush(trace->file);
185*d83cc019SAndroid Build Coastguard Worker funlockfile(trace->file);
186*d83cc019SAndroid Build Coastguard Worker #undef to_ptr
187*d83cc019SAndroid Build Coastguard Worker }
188*d83cc019SAndroid Build Coastguard Worker
189*d83cc019SAndroid Build Coastguard Worker static void
trace_wait(struct trace * trace,uint32_t handle)190*d83cc019SAndroid Build Coastguard Worker trace_wait(struct trace *trace, uint32_t handle)
191*d83cc019SAndroid Build Coastguard Worker {
192*d83cc019SAndroid Build Coastguard Worker struct trace_wait t = { WAIT, handle };
193*d83cc019SAndroid Build Coastguard Worker fwrite(&t, sizeof(t), 1, trace->file);
194*d83cc019SAndroid Build Coastguard Worker }
195*d83cc019SAndroid Build Coastguard Worker
196*d83cc019SAndroid Build Coastguard Worker static void
trace_add(struct trace * trace,uint32_t handle,uint64_t size)197*d83cc019SAndroid Build Coastguard Worker trace_add(struct trace *trace, uint32_t handle, uint64_t size)
198*d83cc019SAndroid Build Coastguard Worker {
199*d83cc019SAndroid Build Coastguard Worker struct trace_add_bo t = { ADD_BO, handle, size };
200*d83cc019SAndroid Build Coastguard Worker fwrite(&t, sizeof(t), 1, trace->file);
201*d83cc019SAndroid Build Coastguard Worker }
202*d83cc019SAndroid Build Coastguard Worker
203*d83cc019SAndroid Build Coastguard Worker static void
trace_del(struct trace * trace,uint32_t handle)204*d83cc019SAndroid Build Coastguard Worker trace_del(struct trace *trace, uint32_t handle)
205*d83cc019SAndroid Build Coastguard Worker {
206*d83cc019SAndroid Build Coastguard Worker struct trace_del_bo t = { DEL_BO, handle };
207*d83cc019SAndroid Build Coastguard Worker fwrite(&t, sizeof(t), 1, trace->file);
208*d83cc019SAndroid Build Coastguard Worker }
209*d83cc019SAndroid Build Coastguard Worker
210*d83cc019SAndroid Build Coastguard Worker static void
trace_add_context(struct trace * trace,uint32_t handle)211*d83cc019SAndroid Build Coastguard Worker trace_add_context(struct trace *trace, uint32_t handle)
212*d83cc019SAndroid Build Coastguard Worker {
213*d83cc019SAndroid Build Coastguard Worker struct trace_add_ctx t = { ADD_CTX, handle };
214*d83cc019SAndroid Build Coastguard Worker fwrite(&t, sizeof(t), 1, trace->file);
215*d83cc019SAndroid Build Coastguard Worker }
216*d83cc019SAndroid Build Coastguard Worker
217*d83cc019SAndroid Build Coastguard Worker static void
trace_del_context(struct trace * trace,uint32_t handle)218*d83cc019SAndroid Build Coastguard Worker trace_del_context(struct trace *trace, uint32_t handle)
219*d83cc019SAndroid Build Coastguard Worker {
220*d83cc019SAndroid Build Coastguard Worker struct trace_del_ctx t = { DEL_CTX, handle };
221*d83cc019SAndroid Build Coastguard Worker fwrite(&t, sizeof(t), 1, trace->file);
222*d83cc019SAndroid Build Coastguard Worker }
223*d83cc019SAndroid Build Coastguard Worker
224*d83cc019SAndroid Build Coastguard Worker int
close(int fd)225*d83cc019SAndroid Build Coastguard Worker close(int fd)
226*d83cc019SAndroid Build Coastguard Worker {
227*d83cc019SAndroid Build Coastguard Worker struct trace *t, **p;
228*d83cc019SAndroid Build Coastguard Worker
229*d83cc019SAndroid Build Coastguard Worker pthread_mutex_lock(&mutex);
230*d83cc019SAndroid Build Coastguard Worker for (p = &traces; (t = *p); p = &t->next) {
231*d83cc019SAndroid Build Coastguard Worker if (t->fd == fd) {
232*d83cc019SAndroid Build Coastguard Worker *p = t->next;
233*d83cc019SAndroid Build Coastguard Worker fclose(t->file);
234*d83cc019SAndroid Build Coastguard Worker free(t);
235*d83cc019SAndroid Build Coastguard Worker break;
236*d83cc019SAndroid Build Coastguard Worker }
237*d83cc019SAndroid Build Coastguard Worker }
238*d83cc019SAndroid Build Coastguard Worker pthread_mutex_unlock(&mutex);
239*d83cc019SAndroid Build Coastguard Worker
240*d83cc019SAndroid Build Coastguard Worker return libc_close(fd);
241*d83cc019SAndroid Build Coastguard Worker }
242*d83cc019SAndroid Build Coastguard Worker
243*d83cc019SAndroid Build Coastguard Worker static unsigned long
size_for_fb(const struct drm_mode_fb_cmd * cmd)244*d83cc019SAndroid Build Coastguard Worker size_for_fb(const struct drm_mode_fb_cmd *cmd)
245*d83cc019SAndroid Build Coastguard Worker {
246*d83cc019SAndroid Build Coastguard Worker unsigned long size;
247*d83cc019SAndroid Build Coastguard Worker
248*d83cc019SAndroid Build Coastguard Worker #ifndef ALIGN
249*d83cc019SAndroid Build Coastguard Worker #define ALIGN(x, y) (((x) + (y) - 1) & -(y))
250*d83cc019SAndroid Build Coastguard Worker #endif
251*d83cc019SAndroid Build Coastguard Worker
252*d83cc019SAndroid Build Coastguard Worker size = ALIGN(cmd->width * cmd->bpp, 64);
253*d83cc019SAndroid Build Coastguard Worker size *= cmd->height;
254*d83cc019SAndroid Build Coastguard Worker return ALIGN(size, 4096);
255*d83cc019SAndroid Build Coastguard Worker }
256*d83cc019SAndroid Build Coastguard Worker
is_i915(int fd)257*d83cc019SAndroid Build Coastguard Worker static int is_i915(int fd)
258*d83cc019SAndroid Build Coastguard Worker {
259*d83cc019SAndroid Build Coastguard Worker drm_version_t v;
260*d83cc019SAndroid Build Coastguard Worker char name[5] = "";
261*d83cc019SAndroid Build Coastguard Worker
262*d83cc019SAndroid Build Coastguard Worker memset(&v, 0, sizeof(v));
263*d83cc019SAndroid Build Coastguard Worker v.name_len = 4;
264*d83cc019SAndroid Build Coastguard Worker v.name = name;
265*d83cc019SAndroid Build Coastguard Worker
266*d83cc019SAndroid Build Coastguard Worker if (libc_ioctl(fd, DRM_IOCTL_VERSION, &v))
267*d83cc019SAndroid Build Coastguard Worker return 0;
268*d83cc019SAndroid Build Coastguard Worker
269*d83cc019SAndroid Build Coastguard Worker return strcmp(name, "i915") == 0;
270*d83cc019SAndroid Build Coastguard Worker }
271*d83cc019SAndroid Build Coastguard Worker
272*d83cc019SAndroid Build Coastguard Worker #define LOCAL_IOCTL_I915_GEM_EXECBUFFER2_WR \
273*d83cc019SAndroid Build Coastguard Worker DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
274*d83cc019SAndroid Build Coastguard Worker
275*d83cc019SAndroid Build Coastguard Worker int
ioctl(int fd,unsigned long request,...)276*d83cc019SAndroid Build Coastguard Worker ioctl(int fd, unsigned long request, ...)
277*d83cc019SAndroid Build Coastguard Worker {
278*d83cc019SAndroid Build Coastguard Worker struct trace *t, **p;
279*d83cc019SAndroid Build Coastguard Worker va_list args;
280*d83cc019SAndroid Build Coastguard Worker void *argp;
281*d83cc019SAndroid Build Coastguard Worker int ret;
282*d83cc019SAndroid Build Coastguard Worker
283*d83cc019SAndroid Build Coastguard Worker va_start(args, request);
284*d83cc019SAndroid Build Coastguard Worker argp = va_arg(args, void *);
285*d83cc019SAndroid Build Coastguard Worker va_end(args);
286*d83cc019SAndroid Build Coastguard Worker
287*d83cc019SAndroid Build Coastguard Worker if (_IOC_TYPE(request) != DRM_IOCTL_BASE)
288*d83cc019SAndroid Build Coastguard Worker goto untraced;
289*d83cc019SAndroid Build Coastguard Worker
290*d83cc019SAndroid Build Coastguard Worker pthread_mutex_lock(&mutex);
291*d83cc019SAndroid Build Coastguard Worker for (p = &traces; (t = *p); p = &t->next) {
292*d83cc019SAndroid Build Coastguard Worker if (fd == t->fd) {
293*d83cc019SAndroid Build Coastguard Worker if (traces != t) {
294*d83cc019SAndroid Build Coastguard Worker *p = t->next;
295*d83cc019SAndroid Build Coastguard Worker t->next = traces;
296*d83cc019SAndroid Build Coastguard Worker traces = t;
297*d83cc019SAndroid Build Coastguard Worker }
298*d83cc019SAndroid Build Coastguard Worker break;
299*d83cc019SAndroid Build Coastguard Worker }
300*d83cc019SAndroid Build Coastguard Worker }
301*d83cc019SAndroid Build Coastguard Worker if (!t) {
302*d83cc019SAndroid Build Coastguard Worker char filename[80];
303*d83cc019SAndroid Build Coastguard Worker
304*d83cc019SAndroid Build Coastguard Worker if (!is_i915(fd)) {
305*d83cc019SAndroid Build Coastguard Worker pthread_mutex_unlock(&mutex);
306*d83cc019SAndroid Build Coastguard Worker goto untraced;
307*d83cc019SAndroid Build Coastguard Worker }
308*d83cc019SAndroid Build Coastguard Worker
309*d83cc019SAndroid Build Coastguard Worker t = malloc(sizeof(*t));
310*d83cc019SAndroid Build Coastguard Worker if (!t) {
311*d83cc019SAndroid Build Coastguard Worker pthread_mutex_unlock(&mutex);
312*d83cc019SAndroid Build Coastguard Worker return -ENOMEM;
313*d83cc019SAndroid Build Coastguard Worker }
314*d83cc019SAndroid Build Coastguard Worker
315*d83cc019SAndroid Build Coastguard Worker sprintf(filename, "/tmp/trace-%d.%d", getpid(), fd);
316*d83cc019SAndroid Build Coastguard Worker t->file = fopen(filename, "w+");
317*d83cc019SAndroid Build Coastguard Worker t->fd = fd;
318*d83cc019SAndroid Build Coastguard Worker
319*d83cc019SAndroid Build Coastguard Worker if (!fwrite(&version, sizeof(version), 1, t->file)) {
320*d83cc019SAndroid Build Coastguard Worker pthread_mutex_unlock(&mutex);
321*d83cc019SAndroid Build Coastguard Worker fclose(t->file);
322*d83cc019SAndroid Build Coastguard Worker free(t);
323*d83cc019SAndroid Build Coastguard Worker return -ENOMEM;
324*d83cc019SAndroid Build Coastguard Worker }
325*d83cc019SAndroid Build Coastguard Worker
326*d83cc019SAndroid Build Coastguard Worker t->next = traces;
327*d83cc019SAndroid Build Coastguard Worker traces = t;
328*d83cc019SAndroid Build Coastguard Worker }
329*d83cc019SAndroid Build Coastguard Worker pthread_mutex_unlock(&mutex);
330*d83cc019SAndroid Build Coastguard Worker
331*d83cc019SAndroid Build Coastguard Worker switch (request) {
332*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_I915_GEM_EXECBUFFER2:
333*d83cc019SAndroid Build Coastguard Worker case LOCAL_IOCTL_I915_GEM_EXECBUFFER2_WR:
334*d83cc019SAndroid Build Coastguard Worker trace_exec(t, argp);
335*d83cc019SAndroid Build Coastguard Worker break;
336*d83cc019SAndroid Build Coastguard Worker
337*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_GEM_CLOSE: {
338*d83cc019SAndroid Build Coastguard Worker struct drm_gem_close *close = argp;
339*d83cc019SAndroid Build Coastguard Worker trace_del(t, close->handle);
340*d83cc019SAndroid Build Coastguard Worker break;
341*d83cc019SAndroid Build Coastguard Worker }
342*d83cc019SAndroid Build Coastguard Worker
343*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_I915_GEM_CONTEXT_DESTROY: {
344*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_destroy *close = argp;
345*d83cc019SAndroid Build Coastguard Worker trace_del_context(t, close->ctx_id);
346*d83cc019SAndroid Build Coastguard Worker break;
347*d83cc019SAndroid Build Coastguard Worker }
348*d83cc019SAndroid Build Coastguard Worker
349*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_I915_GEM_WAIT: {
350*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_wait *w = argp;
351*d83cc019SAndroid Build Coastguard Worker trace_wait(t, w->bo_handle);
352*d83cc019SAndroid Build Coastguard Worker break;
353*d83cc019SAndroid Build Coastguard Worker }
354*d83cc019SAndroid Build Coastguard Worker
355*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_I915_GEM_SET_DOMAIN: {
356*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_set_domain *w = argp;
357*d83cc019SAndroid Build Coastguard Worker trace_wait(t, w->handle);
358*d83cc019SAndroid Build Coastguard Worker break;
359*d83cc019SAndroid Build Coastguard Worker }
360*d83cc019SAndroid Build Coastguard Worker }
361*d83cc019SAndroid Build Coastguard Worker
362*d83cc019SAndroid Build Coastguard Worker ret = libc_ioctl(fd, request, argp);
363*d83cc019SAndroid Build Coastguard Worker if (ret)
364*d83cc019SAndroid Build Coastguard Worker return ret;
365*d83cc019SAndroid Build Coastguard Worker
366*d83cc019SAndroid Build Coastguard Worker switch (request) {
367*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_I915_GEM_CREATE: {
368*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_create *create = argp;
369*d83cc019SAndroid Build Coastguard Worker trace_add(t, create->handle, create->size);
370*d83cc019SAndroid Build Coastguard Worker break;
371*d83cc019SAndroid Build Coastguard Worker }
372*d83cc019SAndroid Build Coastguard Worker
373*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_I915_GEM_USERPTR: {
374*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_userptr *userptr = argp;
375*d83cc019SAndroid Build Coastguard Worker trace_add(t, userptr->handle, userptr->user_size);
376*d83cc019SAndroid Build Coastguard Worker break;
377*d83cc019SAndroid Build Coastguard Worker }
378*d83cc019SAndroid Build Coastguard Worker
379*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_GEM_OPEN: {
380*d83cc019SAndroid Build Coastguard Worker struct drm_gem_open *open = argp;
381*d83cc019SAndroid Build Coastguard Worker trace_add(t, open->handle, open->size);
382*d83cc019SAndroid Build Coastguard Worker break;
383*d83cc019SAndroid Build Coastguard Worker }
384*d83cc019SAndroid Build Coastguard Worker
385*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_PRIME_FD_TO_HANDLE: {
386*d83cc019SAndroid Build Coastguard Worker struct drm_prime_handle *prime = argp;
387*d83cc019SAndroid Build Coastguard Worker off_t size = lseek(prime->fd, 0, SEEK_END);
388*d83cc019SAndroid Build Coastguard Worker fail_if(size == -1, "failed to get prime bo size\n");
389*d83cc019SAndroid Build Coastguard Worker trace_add(t, prime->handle, size);
390*d83cc019SAndroid Build Coastguard Worker break;
391*d83cc019SAndroid Build Coastguard Worker }
392*d83cc019SAndroid Build Coastguard Worker
393*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_MODE_GETFB: {
394*d83cc019SAndroid Build Coastguard Worker struct drm_mode_fb_cmd *cmd = argp;
395*d83cc019SAndroid Build Coastguard Worker trace_add(t, cmd->handle, size_for_fb(cmd));
396*d83cc019SAndroid Build Coastguard Worker break;
397*d83cc019SAndroid Build Coastguard Worker }
398*d83cc019SAndroid Build Coastguard Worker
399*d83cc019SAndroid Build Coastguard Worker case DRM_IOCTL_I915_GEM_CONTEXT_CREATE: {
400*d83cc019SAndroid Build Coastguard Worker struct drm_i915_gem_context_create *create = argp;
401*d83cc019SAndroid Build Coastguard Worker trace_add_context(t, create->ctx_id);
402*d83cc019SAndroid Build Coastguard Worker break;
403*d83cc019SAndroid Build Coastguard Worker }
404*d83cc019SAndroid Build Coastguard Worker }
405*d83cc019SAndroid Build Coastguard Worker
406*d83cc019SAndroid Build Coastguard Worker return 0;
407*d83cc019SAndroid Build Coastguard Worker
408*d83cc019SAndroid Build Coastguard Worker untraced:
409*d83cc019SAndroid Build Coastguard Worker return libc_ioctl(fd, request, argp);
410*d83cc019SAndroid Build Coastguard Worker }
411*d83cc019SAndroid Build Coastguard Worker
412*d83cc019SAndroid Build Coastguard Worker static void __attribute__ ((constructor))
init(void)413*d83cc019SAndroid Build Coastguard Worker init(void)
414*d83cc019SAndroid Build Coastguard Worker {
415*d83cc019SAndroid Build Coastguard Worker libc_close = dlsym(RTLD_NEXT, "close");
416*d83cc019SAndroid Build Coastguard Worker libc_ioctl = dlsym(RTLD_NEXT, "ioctl");
417*d83cc019SAndroid Build Coastguard Worker fail_if(libc_close == NULL || libc_ioctl == NULL,
418*d83cc019SAndroid Build Coastguard Worker "failed to get libc ioctl or close\n");
419*d83cc019SAndroid Build Coastguard Worker }
420