blob: 434c13ad23131628d384e2704b5885b86fb779b9 [file] [log] [blame]
Chris Wilson9eb4de12010-02-12 13:28:40 +00001/*
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 <stdio.h>
43#include <stdlib.h>
44#include <stdarg.h>
45#include <string.h>
Chris Wilsona3a78632010-12-01 21:51:59 +000046#include <unistd.h>
Chris Wilson9eb4de12010-02-12 13:28:40 +000047#include <inttypes.h>
48#include <errno.h>
49#include <sys/stat.h>
50#include <err.h>
Imre Deak5efd3d32012-10-10 16:04:39 +030051#include <assert.h>
Daniel Vetter7ee9f162012-01-09 23:38:17 +010052#include <intel_bufmgr.h>
Chris Wilson9eb4de12010-02-12 13:28:40 +000053
Chris Wilson9eb4de12010-02-12 13:28:40 +000054#include "intel_chipset.h"
55#include "intel_gpu_tools.h"
56#include "instdone.h"
57
Ben Widawskyafeb4312013-04-22 11:36:03 -070058static uint32_t
59print_head(unsigned int reg)
60{
61 printf(" head = 0x%08x, wraps = %d\n", reg & (0x7ffff<<2), reg >> 21);
62 return reg & (0x7ffff<<2);
63}
64
Chris Wilson9eb4de12010-02-12 13:28:40 +000065static void
Ben Widawsky155aa1e2013-04-22 11:07:35 -070066print_instdone(uint32_t devid, unsigned int instdone, unsigned int instdone1)
Chris Wilson9eb4de12010-02-12 13:28:40 +000067{
Ben Widawsky155aa1e2013-04-22 11:07:35 -070068 int i;
69 static int once;
Chris Wilson95374222010-04-08 11:56:57 +010070
Ben Widawsky155aa1e2013-04-22 11:07:35 -070071 if (!once) {
72 init_instdone_definitions(devid);
73 once = 1;
Chris Wilson9eb4de12010-02-12 13:28:40 +000074 }
75
Ben Widawsky155aa1e2013-04-22 11:07:35 -070076 for (i = 0; i < num_instdone_bits; i++) {
77 int busy = 0;
78
79 if (instdone_bits[i].reg == INST_DONE_1) {
80 if (!(instdone1 & instdone_bits[i].bit))
81 busy = 1;
82 } else {
83 if (!(instdone & instdone_bits[i].bit))
84 busy = 1;
85 }
86
87 if (busy)
88 printf(" busy: %s\n", instdone_bits[i].name);
89 }
Chris Wilson9eb4de12010-02-12 13:28:40 +000090}
91
92static void
Chris Wilsonbfc2b532010-03-04 21:56:04 +000093print_i830_pgtbl_err(unsigned int reg)
94{
95 const char *str;
96
97 switch((reg >> 3) & 0xf) {
98 case 0x1: str = "Overlay TLB"; break;
99 case 0x2: str = "Display A TLB"; break;
100 case 0x3: str = "Host TLB"; break;
101 case 0x4: str = "Render TLB"; break;
102 case 0x5: str = "Display C TLB"; break;
103 case 0x6: str = "Mapping TLB"; break;
104 case 0x7: str = "Command Stream TLB"; break;
105 case 0x8: str = "Vertex Buffer TLB"; break;
106 case 0x9: str = "Display B TLB"; break;
107 case 0xa: str = "Reserved System Memory"; break;
108 case 0xb: str = "Compressor TLB"; break;
109 case 0xc: str = "Binner TLB"; break;
110 default: str = "unknown"; break;
111 }
112
113 if (str)
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700114 printf(" source = %s\n", str);
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000115
116 switch(reg & 0x7) {
117 case 0x0: str = "Invalid GTT"; break;
118 case 0x1: str = "Invalid GTT PTE"; break;
119 case 0x2: str = "Invalid Memory"; break;
120 case 0x3: str = "Invalid TLB miss"; break;
121 case 0x4: str = "Invalid PTE data"; break;
122 case 0x5: str = "Invalid LocalMemory not present"; break;
123 case 0x6: str = "Invalid Tiling"; break;
124 case 0x7: str = "Host to CAM"; break;
125 }
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700126 printf(" error = %s\n", str);
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000127}
128
129static void
Chris Wilson2d1ad952010-07-15 19:18:39 +0100130print_i915_pgtbl_err(unsigned int reg)
131{
132 if (reg & (1 << 29))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700133 printf(" Cursor A: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100134 if (reg & (1 << 28))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700135 printf(" Cursor B: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100136 if (reg & (1 << 27))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700137 printf(" MT: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100138 if (reg & (1 << 26))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700139 printf(" MT: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100140 if (reg & (1 << 25))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700141 printf(" LC: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100142 if (reg & (1 << 24))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700143 printf(" LC: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100144 if (reg & (1 << 23))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700145 printf(" BIN VertexData: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100146 if (reg & (1 << 22))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700147 printf(" BIN Instruction: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100148 if (reg & (1 << 21))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700149 printf(" CS VertexData: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100150 if (reg & (1 << 20))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700151 printf(" CS Instruction: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100152 if (reg & (1 << 19))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700153 printf(" CS: Invalid GTT\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100154 if (reg & (1 << 18))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700155 printf(" Overlay: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100156 if (reg & (1 << 16))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700157 printf(" Overlay: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100158 if (reg & (1 << 14))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700159 printf(" Display C: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100160 if (reg & (1 << 12))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700161 printf(" Display C: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100162 if (reg & (1 << 10))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700163 printf(" Display B: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100164 if (reg & (1 << 8))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700165 printf(" Display B: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100166 if (reg & (1 << 6))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700167 printf(" Display A: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100168 if (reg & (1 << 4))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700169 printf(" Display A: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100170 if (reg & (1 << 1))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700171 printf(" Host Invalid PTE data\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100172 if (reg & (1 << 0))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700173 printf(" Host Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100174}
175
176static void
Chris Wilson89343952010-10-22 11:33:08 +0100177print_i965_pgtbl_err(unsigned int reg)
178{
179 if (reg & (1 << 26))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700180 printf(" Invalid Sampler Cache GTT entry\n");
Chris Wilson89343952010-10-22 11:33:08 +0100181 if (reg & (1 << 24))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700182 printf(" Invalid Render Cache GTT entry\n");
Chris Wilson89343952010-10-22 11:33:08 +0100183 if (reg & (1 << 23))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700184 printf(" Invalid Instruction/State Cache GTT entry\n");
Chris Wilson89343952010-10-22 11:33:08 +0100185 if (reg & (1 << 22))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700186 printf(" There is no ROC, this cannot occur!\n");
Chris Wilson89343952010-10-22 11:33:08 +0100187 if (reg & (1 << 21))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700188 printf(" Invalid GTT entry during Vertex Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100189 if (reg & (1 << 20))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700190 printf(" Invalid GTT entry during Command Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100191 if (reg & (1 << 19))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700192 printf(" Invalid GTT entry during CS\n");
Chris Wilson89343952010-10-22 11:33:08 +0100193 if (reg & (1 << 18))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700194 printf(" Invalid GTT entry during Cursor Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100195 if (reg & (1 << 17))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700196 printf(" Invalid GTT entry during Overlay Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100197 if (reg & (1 << 8))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700198 printf(" Invalid GTT entry during Display B Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100199 if (reg & (1 << 4))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700200 printf(" Invalid GTT entry during Display A Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100201 if (reg & (1 << 1))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700202 printf(" Valid PTE references illegal memory\n");
Chris Wilson89343952010-10-22 11:33:08 +0100203 if (reg & (1 << 0))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700204 printf(" Invalid GTT entry during fetch for host\n");
Chris Wilson89343952010-10-22 11:33:08 +0100205}
206
207static void
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000208print_pgtbl_err(unsigned int reg, unsigned int devid)
209{
210 if (IS_965(devid)) {
Chris Wilson89343952010-10-22 11:33:08 +0100211 return print_i965_pgtbl_err(reg);
Chris Wilson41570d92011-02-14 15:56:14 +0000212 } else if (IS_GEN3(devid)) {
Chris Wilson2d1ad952010-07-15 19:18:39 +0100213 return print_i915_pgtbl_err(reg);
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000214 } else {
215 return print_i830_pgtbl_err(reg);
216 }
217}
218
219static void
Daniel Vetterd5109532011-10-21 19:06:08 +0200220print_snb_fence(unsigned int devid, uint64_t fence)
221{
222 printf(" %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %u\n",
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700223 fence & 1 ? "" : "in",
224 fence & (1<<1) ? 'y' : 'x',
225 (int)(((fence>>32)&0xfff)+1)*128,
226 (uint32_t)fence & 0xfffff000,
227 (uint32_t)(((fence>>32)&0xfffff000) - (fence&0xfffff000) + 4096));
Daniel Vetterd5109532011-10-21 19:06:08 +0200228}
229
230static void
231print_i965_fence(unsigned int devid, uint64_t fence)
232{
233 printf(" %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %u\n",
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700234 fence & 1 ? "" : "in",
235 fence & (1<<1) ? 'y' : 'x',
236 (int)(((fence>>2)&0x1ff)+1)*128,
237 (uint32_t)fence & 0xfffff000,
238 (uint32_t)(((fence>>32)&0xfffff000) - (fence&0xfffff000) + 4096));
Daniel Vetterd5109532011-10-21 19:06:08 +0200239}
240
241static void
Daniel Vettercf5db112011-03-14 11:20:17 +0100242print_i915_fence(unsigned int devid, uint64_t fence)
243{
244 unsigned tile_width;
245 if ((fence & 12) && !IS_915(devid))
246 tile_width = 128;
247 else
248 tile_width = 512;
249
250 printf(" %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %i\n",
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700251 fence & 1 ? "" : "in",
252 fence & 12 ? 'y' : 'x',
253 (1<<((fence>>4)&0xf))*tile_width,
254 (uint32_t)fence & 0xff00000,
255 1<<(20 + ((fence>>8)&0xf)));
Daniel Vettercf5db112011-03-14 11:20:17 +0100256}
257
258static void
259print_i830_fence(unsigned int devid, uint64_t fence)
260{
261 printf(" %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %i\n",
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700262 fence & 1 ? "" : "in",
263 fence & 12 ? 'y' : 'x',
264 (1<<((fence>>4)&0xf))*128,
265 (uint32_t)fence & 0x7f80000,
266 1<<(19 + ((fence>>8)&0xf)));
Daniel Vettercf5db112011-03-14 11:20:17 +0100267}
268
269static void
270print_fence(unsigned int devid, uint64_t fence)
271{
Daniel Vetterd5109532011-10-21 19:06:08 +0200272 if (IS_GEN6(devid) || IS_GEN7(devid)) {
273 return print_snb_fence(devid, fence);
274 } else if (IS_GEN4(devid) || IS_GEN5(devid)) {
275 return print_i965_fence(devid, fence);
Daniel Vettercf5db112011-03-14 11:20:17 +0100276 } else if (IS_GEN3(devid)) {
277 return print_i915_fence(devid, fence);
278 } else {
279 return print_i830_fence(devid, fence);
280 }
281}
282
Ben Widawskyafeb4312013-04-22 11:36:03 -0700283#define MAX_RINGS 10 /* I really hope this never... */
284uint32_t head[MAX_RINGS];
285int head_ndx = 0;
286int num_rings = -1;
287static void print_batch(int is_batch, const char *ring_name, uint32_t gtt_offset)
288{
289 const char *buffer_type[2] = { "ringbuffer", "batchbuffer" };
290 if (is_batch) {
291 printf("%s (%s) at 0x%08x\n", buffer_type[is_batch], ring_name, gtt_offset);
292 } else {
293 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);
294 }
295}
296
Daniel Vettercf5db112011-03-14 11:20:17 +0100297static void
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700298read_data_file(FILE *file)
Chris Wilson9eb4de12010-02-12 13:28:40 +0000299{
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700300 struct drm_intel_decode *decode_ctx = NULL;
301 uint32_t devid = PCI_CHIP_I855_GM;
302 uint32_t *data = NULL;
303 long long unsigned fence;
304 int data_size = 0, count = 0, line_number = 0, matched;
305 char *line = NULL;
306 size_t line_size;
307 uint32_t offset, value;
308 uint32_t gtt_offset = 0, new_gtt_offset;
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700309 char *ring_name = NULL;
310 int is_batch = 1;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000311
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700312 while (getline(&line, &line_size, file) > 0) {
313 char *dashes;
314 line_number++;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000315
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700316 dashes = strstr(line, "---");
317 if (dashes) {
318 char *new_ring_name = malloc(dashes - line);
319 strncpy(new_ring_name, line, dashes - line);
320 new_ring_name[dashes - line - 1] = '\0';
Daniel Vetter73c21042011-10-11 13:14:02 +0200321
Ben Widawskyafeb4312013-04-22 11:36:03 -0700322 if (num_rings == -1)
323 num_rings = head_ndx;
324
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700325 matched = sscanf(dashes, "--- gtt_offset = 0x%08x\n",
326 &new_gtt_offset);
327 if (matched == 1) {
328 if (count) {
Ben Widawskyafeb4312013-04-22 11:36:03 -0700329 print_batch(is_batch, ring_name, gtt_offset);
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700330 drm_intel_decode_set_batch_pointer(decode_ctx,
331 data, gtt_offset,
332 count);
333 drm_intel_decode(decode_ctx);
334 count = 0;
335 }
336 gtt_offset = new_gtt_offset;
337 is_batch = 1;
338 free(ring_name);
339 ring_name = new_ring_name;
340 continue;
341 }
342
343 matched = sscanf(dashes, "--- ringbuffer = 0x%08x\n",
344 &new_gtt_offset);
345 if (matched == 1) {
346 if (count) {
Ben Widawskyafeb4312013-04-22 11:36:03 -0700347 print_batch(is_batch, ring_name, gtt_offset);
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700348 drm_intel_decode_set_batch_pointer(decode_ctx,
349 data, gtt_offset,
350 count);
351 drm_intel_decode(decode_ctx);
352 count = 0;
353 }
354 gtt_offset = new_gtt_offset;
355 is_batch = 0;
356 free(ring_name);
357 ring_name = new_ring_name;
358 continue;
359 }
360 }
361
362 matched = sscanf(line, "%08x : %08x", &offset, &value);
363 if (matched != 2) {
364 unsigned int reg;
365
366 /* display reg section is after the ringbuffers, don't mix them */
Chris Wilson98eb5a52011-01-09 13:26:50 +0000367 if (count) {
Ben Widawskyafeb4312013-04-22 11:36:03 -0700368 print_batch(is_batch, ring_name, gtt_offset);
Daniel Vetter7ee9f162012-01-09 23:38:17 +0100369 drm_intel_decode_set_batch_pointer(decode_ctx,
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700370 data, gtt_offset,
371 count);
Daniel Vetter7ee9f162012-01-09 23:38:17 +0100372 drm_intel_decode(decode_ctx);
Chris Wilson98eb5a52011-01-09 13:26:50 +0000373 count = 0;
374 }
Chris Wilson9eb4de12010-02-12 13:28:40 +0000375
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700376 printf("%s", line);
377
378 matched = sscanf(line, "PCI ID: 0x%04x\n", &reg);
379 if (matched == 0)
380 matched = sscanf(line, " PCI ID: 0x%04x\n", &reg);
381 if (matched == 0) {
382 const char *pci_id_start = strstr(line, "PCI ID");
383 if (pci_id_start)
384 matched = sscanf(pci_id_start, "PCI ID: 0x%04x\n", &reg);
Chris Wilson98eb5a52011-01-09 13:26:50 +0000385 }
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700386 if (matched == 1) {
387 devid = reg;
388 printf("Detected GEN%i chipset\n",
389 intel_gen(devid));
390
391 decode_ctx = drm_intel_decode_context_alloc(devid);
392 }
393
Ben Widawskyafeb4312013-04-22 11:36:03 -0700394 matched = sscanf(line, " HEAD: 0x%08x\n", &reg);
395 if (matched == 1) {
396 head[head_ndx++] = print_head(reg);
397 }
398
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700399 matched = sscanf(line, " ACTHD: 0x%08x\n", &reg);
400 if (matched == 1)
401 drm_intel_decode_set_head_tail(decode_ctx, reg, 0xffffffff);
402
403 matched = sscanf(line, " PGTBL_ER: 0x%08x\n", &reg);
404 if (matched == 1 && reg)
405 print_pgtbl_err(reg, devid);
406
407 matched = sscanf(line, " INSTDONE: 0x%08x\n", &reg);
408 if (matched == 1)
409 print_instdone(devid, reg, -1);
410
411 matched = sscanf(line, " INSTDONE1: 0x%08x\n", &reg);
412 if (matched == 1)
413 print_instdone(devid, -1, reg);
414
415 matched = sscanf(line, " fence[%i] = %Lx\n", &reg, &fence);
416 if (matched == 2)
417 print_fence(devid, fence);
418
Chris Wilson98eb5a52011-01-09 13:26:50 +0000419 continue;
420 }
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700421
422 count++;
423
424 if (count > data_size) {
425 data_size = data_size ? data_size * 2 : 1024;
426 data = realloc(data, data_size * sizeof (uint32_t));
427 if (data == NULL) {
428 fprintf(stderr, "Out of memory.\n");
429 exit(1);
430 }
431 }
432
433 data[count-1] = value;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000434 }
435
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700436 if (count) {
Ben Widawskyafeb4312013-04-22 11:36:03 -0700437 print_batch(is_batch, ring_name, gtt_offset);
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700438 drm_intel_decode_set_batch_pointer(decode_ctx,
439 data, gtt_offset,
440 count);
441 drm_intel_decode(decode_ctx);
Chris Wilson9eb4de12010-02-12 13:28:40 +0000442 }
443
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700444 free(data);
445 free(line);
446 free(ring_name);
Chris Wilson9eb4de12010-02-12 13:28:40 +0000447}
448
449int
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700450main(int argc, char *argv[])
Chris Wilson9eb4de12010-02-12 13:28:40 +0000451{
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700452 FILE *file;
453 const char *path;
454 char *filename = NULL;
455 struct stat st;
456 int error;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000457
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700458 if (argc > 2) {
459 fprintf(stderr,
460 "intel_gpu_decode: Parse an Intel GPU i915_error_state\n"
461 "Usage:\n"
462 "\t%s [<file>]\n"
463 "\n"
464 "With no arguments, debugfs-dri-directory is probed for in "
465 "/debug and \n"
466 "/sys/kernel/debug. Otherwise, it may be "
467 "specified. If a file is given,\n"
468 "it is parsed as an GPU dump in the format of "
469 "/debug/dri/0/i915_error_state.\n",
470 argv[0]);
471 return 1;
472 }
Chris Wilson9eb4de12010-02-12 13:28:40 +0000473
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700474 if (argc == 1) {
475 if (isatty(0)) {
476 path = "/debug/dri";
477 error = stat(path, &st);
478 if (error != 0) {
479 path = "/sys/kernel/debug/dri";
480 error = stat(path, &st);
481 if (error != 0) {
482 errx(1,
483 "Couldn't find i915 debugfs directory.\n\n"
484 "Is debugfs mounted? You might try mounting it with a command such as:\n\n"
485 "\tsudo mount -t debugfs debugfs /sys/kernel/debug\n");
486 }
487 }
488 } else {
489 read_data_file(stdin);
490 exit(0);
Chris Wilsona3a78632010-12-01 21:51:59 +0000491 }
Chris Wilsona3a78632010-12-01 21:51:59 +0000492 } else {
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700493 path = argv[1];
494 error = stat(path, &st);
495 if (error != 0) {
496 fprintf(stderr, "Error opening %s: %s\n",
497 path, strerror(errno));
498 exit(1);
499 }
Chris Wilson9eb4de12010-02-12 13:28:40 +0000500 }
Chris Wilson9eb4de12010-02-12 13:28:40 +0000501
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700502 if (S_ISDIR(st.st_mode)) {
503 int ret;
Imre Deak5efd3d32012-10-10 16:04:39 +0300504
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700505 ret = asprintf(&filename, "%s/i915_error_state", path);
Imre Deak5efd3d32012-10-10 16:04:39 +0300506 assert(ret > 0);
Chris Wilson68a95f02011-01-25 16:34:08 +0000507 file = fopen(filename, "r");
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700508 if (!file) {
509 int minor;
510 for (minor = 0; minor < 64; minor++) {
511 free(filename);
512 ret = asprintf(&filename, "%s/%d/i915_error_state", path, minor);
513 assert(ret > 0);
Chris Wilson9eb4de12010-02-12 13:28:40 +0000514
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700515 file = fopen(filename, "r");
516 if (file)
517 break;
518 }
519 }
520 if (!file) {
521 fprintf(stderr, "Failed to find i915_error_state beneath %s\n",
522 path);
523 exit (1);
524 }
525 } else {
526 file = fopen(path, "r");
527 if (!file) {
528 fprintf(stderr, "Failed to open %s: %s\n",
529 path, strerror(errno));
530 exit (1);
531 }
532 }
Chris Wilson68a95f02011-01-25 16:34:08 +0000533
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700534 read_data_file(file);
535 fclose(file);
Chris Wilsona3a78632010-12-01 21:51:59 +0000536
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700537 if (filename != path)
538 free(filename);
539
540 return 0;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000541}
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700542
543/* vim: set ts=8 sw=8 tw=0 noet :*/