kms_fbc_crc: Use I915_TILING_X to create fbs
[platform/upstream/intel-gpu-tools.git] / tools / intel_error_decode.c
1 /*
2  * Copyright © 2007 Intel Corporation
3  * Copyright © 2009 Intel Corporation
4  * Copyright © 2010 Intel Corporation
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23  * IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Eric Anholt <eric@anholt.net>
27  *    Carl Worth <cworth@cworth.org>
28  *    Chris Wilson <chris@chris-wilson.co.uk>
29  *
30  */
31
32 /** @file intel_decode.c
33  * This file contains code to print out batchbuffer contents in a
34  * human-readable format.
35  *
36  * The current version only supports i915 packets, and only pretty-prints a
37  * subset of them.  The intention is for it to make just a best attempt to
38  * decode, but never crash in the process.
39  */
40
41 #define _GNU_SOURCE
42 #include <stdbool.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <stdarg.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <inttypes.h>
49 #include <errno.h>
50 #include <sys/stat.h>
51 #include <err.h>
52 #include <assert.h>
53 #include <intel_bufmgr.h>
54
55 #include "intel_chipset.h"
56 #include "intel_io.h"
57 #include "instdone.h"
58 #include "intel_reg.h"
59
60 static uint32_t
61 print_head(unsigned int reg)
62 {
63         printf("    head = 0x%08x, wraps = %d\n", reg & (0x7ffff<<2), reg >> 21);
64         return reg & (0x7ffff<<2);
65 }
66
67 static uint32_t
68 print_ctl(unsigned int reg)
69 {
70         uint32_t ring_length =  (((reg & (0x1ff << 12)) >> 12) + 1) * 4096;
71
72 #define BIT_STR(reg, x, on, off) ((1 << (x)) & reg) ? on : off
73
74         printf("    len=%d%s%s%s\n", ring_length,
75                BIT_STR(reg, 0, ", enabled", ", disabled"),
76                BIT_STR(reg, 10, ", semaphore wait ", ""),
77                BIT_STR(reg, 11, ", rb wait ", "")
78                 );
79 #undef BIT_STR
80         return ring_length;
81 }
82
83 static void
84 print_acthd(unsigned int reg, unsigned int ring_length)
85 {
86         if ((reg & (0x7ffff << 2)) < ring_length)
87                 printf("    at ring: 0x%08x\n", reg & (0x7ffff << 2));
88         else
89                 printf("    at batch: 0x%08x\n", reg);
90 }
91
92 static void
93 print_instdone(uint32_t devid, unsigned int instdone, unsigned int instdone1)
94 {
95         int i;
96         static int once;
97
98         if (!once) {
99                 init_instdone_definitions(devid);
100                 once = 1;
101         }
102
103         for (i = 0; i < num_instdone_bits; i++) {
104                 int busy = 0;
105
106                 if (instdone_bits[i].reg == INSTDONE_1) {
107                         if (!(instdone1 & instdone_bits[i].bit))
108                                 busy = 1;
109                 } else {
110                         if (!(instdone & instdone_bits[i].bit))
111                                 busy = 1;
112                 }
113
114                 if (busy)
115                         printf("    busy: %s\n", instdone_bits[i].name);
116         }
117 }
118
119 static void
120 print_i830_pgtbl_err(unsigned int reg)
121 {
122         const char *str;
123
124         switch((reg >> 3) & 0xf) {
125         case 0x1: str = "Overlay TLB"; break;
126         case 0x2: str = "Display A TLB"; break;
127         case 0x3: str = "Host TLB"; break;
128         case 0x4: str = "Render TLB"; break;
129         case 0x5: str = "Display C TLB"; break;
130         case 0x6: str = "Mapping TLB"; break;
131         case 0x7: str = "Command Stream TLB"; break;
132         case 0x8: str = "Vertex Buffer TLB"; break;
133         case 0x9: str = "Display B TLB"; break;
134         case 0xa: str = "Reserved System Memory"; break;
135         case 0xb: str = "Compressor TLB"; break;
136         case 0xc: str = "Binner TLB"; break;
137         default: str = "unknown"; break;
138         }
139
140         if (str)
141                 printf("    source = %s\n", str);
142
143         switch(reg & 0x7) {
144         case 0x0: str  = "Invalid GTT"; break;
145         case 0x1: str = "Invalid GTT PTE"; break;
146         case 0x2: str = "Invalid Memory"; break;
147         case 0x3: str = "Invalid TLB miss"; break;
148         case 0x4: str = "Invalid PTE data"; break;
149         case 0x5: str = "Invalid LocalMemory not present"; break;
150         case 0x6: str = "Invalid Tiling"; break;
151         case 0x7: str = "Host to CAM"; break;
152         }
153         printf("    error = %s\n", str);
154 }
155
156 static void
157 print_i915_pgtbl_err(unsigned int reg)
158 {
159         if (reg & (1 << 29))
160                 printf("    Cursor A: Invalid GTT PTE\n");
161         if (reg & (1 << 28))
162                 printf("    Cursor B: Invalid GTT PTE\n");
163         if (reg & (1 << 27))
164                 printf("    MT: Invalid tiling\n");
165         if (reg & (1 << 26))
166                 printf("    MT: Invalid GTT PTE\n");
167         if (reg & (1 << 25))
168                 printf("    LC: Invalid tiling\n");
169         if (reg & (1 << 24))
170                 printf("    LC: Invalid GTT PTE\n");
171         if (reg & (1 << 23))
172                 printf("    BIN VertexData: Invalid GTT PTE\n");
173         if (reg & (1 << 22))
174                 printf("    BIN Instruction: Invalid GTT PTE\n");
175         if (reg & (1 << 21))
176                 printf("    CS VertexData: Invalid GTT PTE\n");
177         if (reg & (1 << 20))
178                 printf("    CS Instruction: Invalid GTT PTE\n");
179         if (reg & (1 << 19))
180                 printf("    CS: Invalid GTT\n");
181         if (reg & (1 << 18))
182                 printf("    Overlay: Invalid tiling\n");
183         if (reg & (1 << 16))
184                 printf("    Overlay: Invalid GTT PTE\n");
185         if (reg & (1 << 14))
186                 printf("    Display C: Invalid tiling\n");
187         if (reg & (1 << 12))
188                 printf("    Display C: Invalid GTT PTE\n");
189         if (reg & (1 << 10))
190                 printf("    Display B: Invalid tiling\n");
191         if (reg & (1 << 8))
192                 printf("    Display B: Invalid GTT PTE\n");
193         if (reg & (1 << 6))
194                 printf("    Display A: Invalid tiling\n");
195         if (reg & (1 << 4))
196                 printf("    Display A: Invalid GTT PTE\n");
197         if (reg & (1 << 1))
198                 printf("    Host Invalid PTE data\n");
199         if (reg & (1 << 0))
200                 printf("    Host Invalid GTT PTE\n");
201 }
202
203 static void
204 print_i965_pgtbl_err(unsigned int reg)
205 {
206         if (reg & (1 << 26))
207                 printf("    Invalid Sampler Cache GTT entry\n");
208         if (reg & (1 << 24))
209                 printf("    Invalid Render Cache GTT entry\n");
210         if (reg & (1 << 23))
211                 printf("    Invalid Instruction/State Cache GTT entry\n");
212         if (reg & (1 << 22))
213                 printf("    There is no ROC, this cannot occur!\n");
214         if (reg & (1 << 21))
215                 printf("    Invalid GTT entry during Vertex Fetch\n");
216         if (reg & (1 << 20))
217                 printf("    Invalid GTT entry during Command Fetch\n");
218         if (reg & (1 << 19))
219                 printf("    Invalid GTT entry during CS\n");
220         if (reg & (1 << 18))
221                 printf("    Invalid GTT entry during Cursor Fetch\n");
222         if (reg & (1 << 17))
223                 printf("    Invalid GTT entry during Overlay Fetch\n");
224         if (reg & (1 << 8))
225                 printf("    Invalid GTT entry during Display B Fetch\n");
226         if (reg & (1 << 4))
227                 printf("    Invalid GTT entry during Display A Fetch\n");
228         if (reg & (1 << 1))
229                 printf("    Valid PTE references illegal memory\n");
230         if (reg & (1 << 0))
231                 printf("    Invalid GTT entry during fetch for host\n");
232 }
233
234 static void
235 print_pgtbl_err(unsigned int reg, unsigned int devid)
236 {
237         if (IS_965(devid)) {
238                 return print_i965_pgtbl_err(reg);
239         } else if (IS_GEN3(devid)) {
240                 return print_i915_pgtbl_err(reg);
241         } else {
242                 return print_i830_pgtbl_err(reg);
243         }
244 }
245
246 static void
247 print_snb_fence(unsigned int devid, uint64_t fence)
248 {
249         printf("    %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %u\n",
250                         fence & 1 ? "" : "in",
251                         fence & (1<<1) ? 'y' : 'x',
252                         (int)(((fence>>32)&0xfff)+1)*128,
253                         (uint32_t)fence & 0xfffff000,
254                         (uint32_t)(((fence>>32)&0xfffff000) - (fence&0xfffff000) + 4096));
255 }
256
257 static void
258 print_i965_fence(unsigned int devid, uint64_t fence)
259 {
260         printf("    %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %u\n",
261                         fence & 1 ? "" : "in",
262                         fence & (1<<1) ? 'y' : 'x',
263                         (int)(((fence>>2)&0x1ff)+1)*128,
264                         (uint32_t)fence & 0xfffff000,
265                         (uint32_t)(((fence>>32)&0xfffff000) - (fence&0xfffff000) + 4096));
266 }
267
268 static void
269 print_i915_fence(unsigned int devid, uint64_t fence)
270 {
271         unsigned tile_width;
272         if ((fence & 12) && !IS_915(devid))
273                 tile_width = 128;
274         else
275                 tile_width = 512;
276
277         printf("    %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %i\n",
278                         fence & 1 ? "" : "in",
279                         fence & (1<<12) ? 'y' : 'x',
280                         (1<<((fence>>4)&0xf))*tile_width,
281                         (uint32_t)fence & 0xff00000,
282                         1<<(20 + ((fence>>8)&0xf)));
283 }
284
285 static void
286 print_i830_fence(unsigned int devid, uint64_t fence)
287 {
288         printf("    %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %i\n",
289                         fence & 1 ? "" : "in",
290                         fence & (1<<12) ? 'y' : 'x',
291                         (1<<((fence>>4)&0xf))*128,
292                         (uint32_t)fence & 0x7f80000,
293                         1<<(19 + ((fence>>8)&0xf)));
294 }
295
296 static void
297 print_fence(unsigned int devid, uint64_t fence)
298 {
299         if (IS_GEN6(devid) || IS_GEN7(devid)) {
300                 return print_snb_fence(devid, fence);
301         } else if (IS_GEN4(devid) || IS_GEN5(devid)) {
302                 return print_i965_fence(devid, fence);
303         } else if (IS_GEN3(devid)) {
304                 return print_i915_fence(devid, fence);
305         } else {
306                 return print_i830_fence(devid, fence);
307         }
308 }
309
310 #define MAX_RINGS 10 /* I really hope this never... */
311 uint32_t head[MAX_RINGS];
312 int head_ndx = 0;
313 int num_rings = 0;
314 static void print_batch(int is_batch, const char *ring_name, uint32_t gtt_offset)
315 {
316         const char *buffer_type[2] = {  "ringbuffer", "batchbuffer" };
317         if (is_batch || !num_rings)
318                 printf("%s (%s) at 0x%08x\n", buffer_type[is_batch], ring_name, gtt_offset);
319         else
320                 printf("%s (%s) at 0x%08x; HEAD points to: 0x%08x\n", buffer_type[is_batch], ring_name, gtt_offset, head[head_ndx++ % num_rings] + gtt_offset);
321 }
322
323 static void decode(struct drm_intel_decode *ctx, bool is_batch,
324                    const char *ring_name, uint32_t gtt_offset, uint32_t *data,
325                    int *count)
326 {
327         if (!*count)
328                 return;
329
330         print_batch(is_batch, ring_name, gtt_offset);
331         drm_intel_decode_set_batch_pointer(ctx, data, gtt_offset, *count);
332         drm_intel_decode(ctx);
333         *count = 0;
334 }
335
336 static void
337 read_data_file(FILE *file)
338 {
339         struct drm_intel_decode *decode_ctx = NULL;
340         uint32_t devid = PCI_CHIP_I855_GM;
341         uint32_t *data = NULL;
342         long long unsigned fence;
343         int data_size = 0, count = 0, line_number = 0, matched;
344         char *line = NULL;
345         size_t line_size;
346         uint32_t offset, value, ring_length = 0;
347         uint32_t gtt_offset = 0, new_gtt_offset;
348         char *ring_name = NULL;
349         int is_batch = 1;
350
351         while (getline(&line, &line_size, file) > 0) {
352                 char *dashes;
353                 line_number++;
354
355                 dashes = strstr(line, "---");
356                 if (dashes) {
357                         char *new_ring_name = malloc(dashes - line);
358                         strncpy(new_ring_name, line, dashes - line);
359                         new_ring_name[dashes - line - 1] = '\0';
360
361                         if (num_rings == -1)
362                                 num_rings = head_ndx;
363
364                         matched = sscanf(dashes, "--- gtt_offset = 0x%08x\n",
365                                         &new_gtt_offset);
366                         if (matched == 1) {
367                                 decode(decode_ctx, is_batch, ring_name,
368                                        gtt_offset, data, &count);
369                                 gtt_offset = new_gtt_offset;
370                                 is_batch = 1;
371                                 free(ring_name);
372                                 ring_name = new_ring_name;
373                                 continue;
374                         }
375
376                         matched = sscanf(dashes, "--- ringbuffer = 0x%08x\n",
377                                         &new_gtt_offset);
378                         if (matched == 1) {
379                                 decode(decode_ctx, is_batch, ring_name,
380                                        gtt_offset, data, &count);
381                                 gtt_offset = new_gtt_offset;
382                                 is_batch = 0;
383                                 free(ring_name);
384                                 ring_name = new_ring_name;
385                                 continue;
386                         }
387                 }
388
389                 matched = sscanf(line, "%08x : %08x", &offset, &value);
390                 if (matched != 2) {
391                         unsigned int reg;
392
393                         /* display reg section is after the ringbuffers, don't mix them */
394                         decode(decode_ctx, is_batch, ring_name, gtt_offset,
395                                data, &count);
396
397                         printf("%s", line);
398
399                         matched = sscanf(line, "PCI ID: 0x%04x\n", &reg);
400                         if (matched == 0)
401                                 matched = sscanf(line, " PCI ID: 0x%04x\n", &reg);
402                         if (matched == 0) {
403                                 const char *pci_id_start = strstr(line, "PCI ID");
404                                 if (pci_id_start)
405                                         matched = sscanf(pci_id_start, "PCI ID: 0x%04x\n", &reg);
406                         }
407                         if (matched == 1) {
408                                 devid = reg;
409                                 printf("Detected GEN%i chipset\n",
410                                                 intel_gen(devid));
411
412                                 decode_ctx = drm_intel_decode_context_alloc(devid);
413                         }
414
415                         matched = sscanf(line, "  CTL: 0x%08x\n", &reg);
416                         if (matched == 1)
417                                 ring_length = print_ctl(reg);
418
419                         matched = sscanf(line, "  HEAD: 0x%08x\n", &reg);
420                         if (matched == 1) {
421                                 head[num_rings++] = print_head(reg);
422                         }
423
424                         matched = sscanf(line, "  ACTHD: 0x%08x\n", &reg);
425                         if (matched == 1) {
426                                 print_acthd(reg, ring_length);
427                                 drm_intel_decode_set_head_tail(decode_ctx, reg, 0xffffffff);
428                         }
429
430                         matched = sscanf(line, "  PGTBL_ER: 0x%08x\n", &reg);
431                         if (matched == 1 && reg)
432                                 print_pgtbl_err(reg, devid);
433
434                         matched = sscanf(line, "  INSTDONE: 0x%08x\n", &reg);
435                         if (matched == 1)
436                                 print_instdone(devid, reg, -1);
437
438                         matched = sscanf(line, "  INSTDONE1: 0x%08x\n", &reg);
439                         if (matched == 1)
440                                 print_instdone(devid, -1, reg);
441
442                         matched = sscanf(line, "  fence[%i] = %Lx\n", &reg, &fence);
443                         if (matched == 2)
444                                 print_fence(devid, fence);
445
446                         continue;
447                 }
448
449                 count++;
450
451                 if (count > data_size) {
452                         data_size = data_size ? data_size * 2 : 1024;
453                         data = realloc(data, data_size * sizeof (uint32_t));
454                         if (data == NULL) {
455                                 fprintf(stderr, "Out of memory.\n");
456                                 exit(1);
457                         }
458                 }
459
460                 data[count-1] = value;
461         }
462
463         decode(decode_ctx, is_batch, ring_name, gtt_offset, data, &count);
464
465         free(data);
466         free(line);
467         free(ring_name);
468 }
469
470 int
471 main(int argc, char *argv[])
472 {
473         FILE *file;
474         const char *path;
475         char *filename = NULL;
476         struct stat st;
477         int error;
478
479         if (argc > 2) {
480                 fprintf(stderr,
481                                 "intel_gpu_decode: Parse an Intel GPU i915_error_state\n"
482                                 "Usage:\n"
483                                 "\t%s [<file>]\n"
484                                 "\n"
485                                 "With no arguments, debugfs-dri-directory is probed for in "
486                                 "/debug and \n"
487                                 "/sys/kernel/debug.  Otherwise, it may be "
488                                 "specified.  If a file is given,\n"
489                                 "it is parsed as an GPU dump in the format of "
490                                 "/debug/dri/0/i915_error_state.\n",
491                                 argv[0]);
492                 return 1;
493         }
494
495         if (argc == 1) {
496                 if (isatty(0)) {
497                         path = "/sys/class/drm/card0/error";
498                         error = stat(path, &st);
499                         if (error != 0) {
500                                 path = "/debug/dri";
501                                 error = stat(path, &st);
502                         }
503                         if (error != 0) {
504                                 path = "/sys/kernel/debug/dri";
505                                 error = stat(path, &st);
506                         }
507                         if (error != 0) {
508                                 errx(1,
509                                      "Couldn't find i915 debugfs directory.\n\n"
510                                      "Is debugfs mounted? You might try mounting it with a command such as:\n\n"
511                                      "\tsudo mount -t debugfs debugfs /sys/kernel/debug\n");
512                         }
513                 } else {
514                         read_data_file(stdin);
515                         exit(0);
516                 }
517         } else {
518                 path = argv[1];
519                 error = stat(path, &st);
520                 if (error != 0) {
521                         fprintf(stderr, "Error opening %s: %s\n",
522                                         path, strerror(errno));
523                         exit(1);
524                 }
525         }
526
527         if (S_ISDIR(st.st_mode)) {
528                 int ret;
529
530                 ret = asprintf(&filename, "%s/i915_error_state", path);
531                 assert(ret > 0);
532                 file = fopen(filename, "r");
533                 if (!file) {
534                         int minor;
535                         for (minor = 0; minor < 64; minor++) {
536                                 free(filename);
537                                 ret = asprintf(&filename, "%s/%d/i915_error_state", path, minor);
538                                 assert(ret > 0);
539
540                                 file = fopen(filename, "r");
541                                 if (file)
542                                         break;
543                         }
544                 }
545                 if (!file) {
546                         fprintf(stderr, "Failed to find i915_error_state beneath %s\n",
547                                         path);
548                         exit (1);
549                 }
550         } else {
551                 file = fopen(path, "r");
552                 if (!file) {
553                         fprintf(stderr, "Failed to open %s: %s\n",
554                                         path, strerror(errno));
555                         exit (1);
556                 }
557         }
558
559         read_data_file(file);
560         fclose(file);
561
562         if (filename != path)
563                 free(filename);
564
565         return 0;
566 }
567
568 /* vim: set ts=8 sw=8 tw=0 noet :*/