blob: fff2aed57830d175ceed17b6c834e394b7cee43e [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
Damien Lespiau1d2ef952013-12-16 11:28:39 +000042#include <stdbool.h>
Chris Wilson9eb4de12010-02-12 13:28:40 +000043#include <stdio.h>
44#include <stdlib.h>
45#include <stdarg.h>
46#include <string.h>
Chris Wilsona3a78632010-12-01 21:51:59 +000047#include <unistd.h>
Chris Wilson9eb4de12010-02-12 13:28:40 +000048#include <inttypes.h>
49#include <errno.h>
50#include <sys/stat.h>
51#include <err.h>
Imre Deak5efd3d32012-10-10 16:04:39 +030052#include <assert.h>
Daniel Vetter7ee9f162012-01-09 23:38:17 +010053#include <intel_bufmgr.h>
Chris Wilson9eb4de12010-02-12 13:28:40 +000054
Chris Wilson9eb4de12010-02-12 13:28:40 +000055#include "intel_chipset.h"
56#include "intel_gpu_tools.h"
57#include "instdone.h"
58
Ben Widawskyafeb4312013-04-22 11:36:03 -070059static uint32_t
60print_head(unsigned int reg)
61{
62 printf(" head = 0x%08x, wraps = %d\n", reg & (0x7ffff<<2), reg >> 21);
63 return reg & (0x7ffff<<2);
64}
65
Mika Kuoppalaedee9522013-07-12 17:02:04 +030066static uint32_t
67print_ctl(unsigned int reg)
68{
69 uint32_t ring_length = (((reg & (0x1ff << 12)) >> 12) + 1) * 4096;
70
71#define BIT_STR(reg, x, on, off) ((1 << (x)) & reg) ? on : off
72
73 printf(" len=%d%s%s%s\n", ring_length,
74 BIT_STR(reg, 0, ", enabled", ", disabled"),
75 BIT_STR(reg, 10, ", semaphore wait ", ""),
76 BIT_STR(reg, 11, ", rb wait ", "")
77 );
78#undef BIT_STR
79 return ring_length;
80}
81
82static void
83print_acthd(unsigned int reg, unsigned int ring_length)
84{
85 if ((reg & (0x7ffff << 2)) < ring_length)
86 printf(" at ring: 0x%08x\n", reg & (0x7ffff << 2));
87 else
88 printf(" at batch: 0x%08x\n", reg);
89}
90
Chris Wilson9eb4de12010-02-12 13:28:40 +000091static void
Ben Widawsky155aa1e2013-04-22 11:07:35 -070092print_instdone(uint32_t devid, unsigned int instdone, unsigned int instdone1)
Chris Wilson9eb4de12010-02-12 13:28:40 +000093{
Ben Widawsky155aa1e2013-04-22 11:07:35 -070094 int i;
95 static int once;
Chris Wilson95374222010-04-08 11:56:57 +010096
Ben Widawsky155aa1e2013-04-22 11:07:35 -070097 if (!once) {
98 init_instdone_definitions(devid);
99 once = 1;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000100 }
101
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700102 for (i = 0; i < num_instdone_bits; i++) {
103 int busy = 0;
104
Damien Lespiaud8b1dee2013-06-04 05:41:36 +0100105 if (instdone_bits[i].reg == INSTDONE_1) {
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700106 if (!(instdone1 & instdone_bits[i].bit))
107 busy = 1;
108 } else {
109 if (!(instdone & instdone_bits[i].bit))
110 busy = 1;
111 }
112
113 if (busy)
114 printf(" busy: %s\n", instdone_bits[i].name);
115 }
Chris Wilson9eb4de12010-02-12 13:28:40 +0000116}
117
118static void
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000119print_i830_pgtbl_err(unsigned int reg)
120{
121 const char *str;
122
123 switch((reg >> 3) & 0xf) {
124 case 0x1: str = "Overlay TLB"; break;
125 case 0x2: str = "Display A TLB"; break;
126 case 0x3: str = "Host TLB"; break;
127 case 0x4: str = "Render TLB"; break;
128 case 0x5: str = "Display C TLB"; break;
129 case 0x6: str = "Mapping TLB"; break;
130 case 0x7: str = "Command Stream TLB"; break;
131 case 0x8: str = "Vertex Buffer TLB"; break;
132 case 0x9: str = "Display B TLB"; break;
133 case 0xa: str = "Reserved System Memory"; break;
134 case 0xb: str = "Compressor TLB"; break;
135 case 0xc: str = "Binner TLB"; break;
136 default: str = "unknown"; break;
137 }
138
139 if (str)
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700140 printf(" source = %s\n", str);
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000141
142 switch(reg & 0x7) {
143 case 0x0: str = "Invalid GTT"; break;
144 case 0x1: str = "Invalid GTT PTE"; break;
145 case 0x2: str = "Invalid Memory"; break;
146 case 0x3: str = "Invalid TLB miss"; break;
147 case 0x4: str = "Invalid PTE data"; break;
148 case 0x5: str = "Invalid LocalMemory not present"; break;
149 case 0x6: str = "Invalid Tiling"; break;
150 case 0x7: str = "Host to CAM"; break;
151 }
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700152 printf(" error = %s\n", str);
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000153}
154
155static void
Chris Wilson2d1ad952010-07-15 19:18:39 +0100156print_i915_pgtbl_err(unsigned int reg)
157{
158 if (reg & (1 << 29))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700159 printf(" Cursor A: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100160 if (reg & (1 << 28))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700161 printf(" Cursor B: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100162 if (reg & (1 << 27))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700163 printf(" MT: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100164 if (reg & (1 << 26))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700165 printf(" MT: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100166 if (reg & (1 << 25))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700167 printf(" LC: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100168 if (reg & (1 << 24))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700169 printf(" LC: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100170 if (reg & (1 << 23))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700171 printf(" BIN VertexData: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100172 if (reg & (1 << 22))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700173 printf(" BIN Instruction: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100174 if (reg & (1 << 21))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700175 printf(" CS VertexData: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100176 if (reg & (1 << 20))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700177 printf(" CS Instruction: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100178 if (reg & (1 << 19))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700179 printf(" CS: Invalid GTT\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100180 if (reg & (1 << 18))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700181 printf(" Overlay: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100182 if (reg & (1 << 16))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700183 printf(" Overlay: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100184 if (reg & (1 << 14))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700185 printf(" Display C: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100186 if (reg & (1 << 12))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700187 printf(" Display C: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100188 if (reg & (1 << 10))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700189 printf(" Display B: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100190 if (reg & (1 << 8))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700191 printf(" Display B: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100192 if (reg & (1 << 6))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700193 printf(" Display A: Invalid tiling\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100194 if (reg & (1 << 4))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700195 printf(" Display A: Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100196 if (reg & (1 << 1))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700197 printf(" Host Invalid PTE data\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100198 if (reg & (1 << 0))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700199 printf(" Host Invalid GTT PTE\n");
Chris Wilson2d1ad952010-07-15 19:18:39 +0100200}
201
202static void
Chris Wilson89343952010-10-22 11:33:08 +0100203print_i965_pgtbl_err(unsigned int reg)
204{
205 if (reg & (1 << 26))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700206 printf(" Invalid Sampler Cache GTT entry\n");
Chris Wilson89343952010-10-22 11:33:08 +0100207 if (reg & (1 << 24))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700208 printf(" Invalid Render Cache GTT entry\n");
Chris Wilson89343952010-10-22 11:33:08 +0100209 if (reg & (1 << 23))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700210 printf(" Invalid Instruction/State Cache GTT entry\n");
Chris Wilson89343952010-10-22 11:33:08 +0100211 if (reg & (1 << 22))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700212 printf(" There is no ROC, this cannot occur!\n");
Chris Wilson89343952010-10-22 11:33:08 +0100213 if (reg & (1 << 21))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700214 printf(" Invalid GTT entry during Vertex Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100215 if (reg & (1 << 20))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700216 printf(" Invalid GTT entry during Command Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100217 if (reg & (1 << 19))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700218 printf(" Invalid GTT entry during CS\n");
Chris Wilson89343952010-10-22 11:33:08 +0100219 if (reg & (1 << 18))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700220 printf(" Invalid GTT entry during Cursor Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100221 if (reg & (1 << 17))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700222 printf(" Invalid GTT entry during Overlay Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100223 if (reg & (1 << 8))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700224 printf(" Invalid GTT entry during Display B Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100225 if (reg & (1 << 4))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700226 printf(" Invalid GTT entry during Display A Fetch\n");
Chris Wilson89343952010-10-22 11:33:08 +0100227 if (reg & (1 << 1))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700228 printf(" Valid PTE references illegal memory\n");
Chris Wilson89343952010-10-22 11:33:08 +0100229 if (reg & (1 << 0))
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700230 printf(" Invalid GTT entry during fetch for host\n");
Chris Wilson89343952010-10-22 11:33:08 +0100231}
232
233static void
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000234print_pgtbl_err(unsigned int reg, unsigned int devid)
235{
236 if (IS_965(devid)) {
Chris Wilson89343952010-10-22 11:33:08 +0100237 return print_i965_pgtbl_err(reg);
Chris Wilson41570d92011-02-14 15:56:14 +0000238 } else if (IS_GEN3(devid)) {
Chris Wilson2d1ad952010-07-15 19:18:39 +0100239 return print_i915_pgtbl_err(reg);
Chris Wilsonbfc2b532010-03-04 21:56:04 +0000240 } else {
241 return print_i830_pgtbl_err(reg);
242 }
243}
244
245static void
Daniel Vetterd5109532011-10-21 19:06:08 +0200246print_snb_fence(unsigned int devid, uint64_t fence)
247{
248 printf(" %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %u\n",
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700249 fence & 1 ? "" : "in",
250 fence & (1<<1) ? 'y' : 'x',
251 (int)(((fence>>32)&0xfff)+1)*128,
252 (uint32_t)fence & 0xfffff000,
253 (uint32_t)(((fence>>32)&0xfffff000) - (fence&0xfffff000) + 4096));
Daniel Vetterd5109532011-10-21 19:06:08 +0200254}
255
256static void
257print_i965_fence(unsigned int devid, uint64_t fence)
258{
259 printf(" %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %u\n",
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700260 fence & 1 ? "" : "in",
261 fence & (1<<1) ? 'y' : 'x',
262 (int)(((fence>>2)&0x1ff)+1)*128,
263 (uint32_t)fence & 0xfffff000,
264 (uint32_t)(((fence>>32)&0xfffff000) - (fence&0xfffff000) + 4096));
Daniel Vetterd5109532011-10-21 19:06:08 +0200265}
266
267static void
Daniel Vettercf5db112011-03-14 11:20:17 +0100268print_i915_fence(unsigned int devid, uint64_t fence)
269{
270 unsigned tile_width;
271 if ((fence & 12) && !IS_915(devid))
272 tile_width = 128;
273 else
274 tile_width = 512;
275
276 printf(" %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %i\n",
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700277 fence & 1 ? "" : "in",
Chris Wilson58ac17d2013-10-21 09:31:18 +0100278 fence & (1<<12) ? 'y' : 'x',
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700279 (1<<((fence>>4)&0xf))*tile_width,
280 (uint32_t)fence & 0xff00000,
281 1<<(20 + ((fence>>8)&0xf)));
Daniel Vettercf5db112011-03-14 11:20:17 +0100282}
283
284static void
285print_i830_fence(unsigned int devid, uint64_t fence)
286{
287 printf(" %svalid, %c-tiled, pitch: %i, start: 0x%08x, size: %i\n",
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700288 fence & 1 ? "" : "in",
Chris Wilson58ac17d2013-10-21 09:31:18 +0100289 fence & (1<<12) ? 'y' : 'x',
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700290 (1<<((fence>>4)&0xf))*128,
291 (uint32_t)fence & 0x7f80000,
292 1<<(19 + ((fence>>8)&0xf)));
Daniel Vettercf5db112011-03-14 11:20:17 +0100293}
294
295static void
296print_fence(unsigned int devid, uint64_t fence)
297{
Daniel Vetterd5109532011-10-21 19:06:08 +0200298 if (IS_GEN6(devid) || IS_GEN7(devid)) {
299 return print_snb_fence(devid, fence);
300 } else if (IS_GEN4(devid) || IS_GEN5(devid)) {
301 return print_i965_fence(devid, fence);
Daniel Vettercf5db112011-03-14 11:20:17 +0100302 } else if (IS_GEN3(devid)) {
303 return print_i915_fence(devid, fence);
304 } else {
305 return print_i830_fence(devid, fence);
306 }
307}
308
Ben Widawskyafeb4312013-04-22 11:36:03 -0700309#define MAX_RINGS 10 /* I really hope this never... */
310uint32_t head[MAX_RINGS];
311int head_ndx = 0;
Chris Wilsonb5109e62014-01-23 21:50:36 +0000312int num_rings = 0;
Ben Widawskyafeb4312013-04-22 11:36:03 -0700313static void print_batch(int is_batch, const char *ring_name, uint32_t gtt_offset)
314{
315 const char *buffer_type[2] = { "ringbuffer", "batchbuffer" };
Chris Wilsonb5109e62014-01-23 21:50:36 +0000316 if (is_batch || !num_rings)
Ben Widawskyafeb4312013-04-22 11:36:03 -0700317 printf("%s (%s) at 0x%08x\n", buffer_type[is_batch], ring_name, gtt_offset);
Chris Wilsonb5109e62014-01-23 21:50:36 +0000318 else
Ben Widawskyafeb4312013-04-22 11:36:03 -0700319 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);
Ben Widawskyafeb4312013-04-22 11:36:03 -0700320}
321
Damien Lespiau1d2ef952013-12-16 11:28:39 +0000322static void decode(struct drm_intel_decode *ctx, bool is_batch,
323 const char *ring_name, uint32_t gtt_offset, uint32_t *data,
324 int *count)
325{
326 if (!*count)
327 return;
328
329 print_batch(is_batch, ring_name, gtt_offset);
330 drm_intel_decode_set_batch_pointer(ctx, data, gtt_offset, *count);
331 drm_intel_decode(ctx);
332 *count = 0;
333}
334
Daniel Vettercf5db112011-03-14 11:20:17 +0100335static void
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700336read_data_file(FILE *file)
Chris Wilson9eb4de12010-02-12 13:28:40 +0000337{
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700338 struct drm_intel_decode *decode_ctx = NULL;
339 uint32_t devid = PCI_CHIP_I855_GM;
340 uint32_t *data = NULL;
341 long long unsigned fence;
342 int data_size = 0, count = 0, line_number = 0, matched;
343 char *line = NULL;
344 size_t line_size;
Mika Kuoppalaedee9522013-07-12 17:02:04 +0300345 uint32_t offset, value, ring_length = 0;
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700346 uint32_t gtt_offset = 0, new_gtt_offset;
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700347 char *ring_name = NULL;
348 int is_batch = 1;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000349
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700350 while (getline(&line, &line_size, file) > 0) {
351 char *dashes;
352 line_number++;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000353
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700354 dashes = strstr(line, "---");
355 if (dashes) {
356 char *new_ring_name = malloc(dashes - line);
357 strncpy(new_ring_name, line, dashes - line);
358 new_ring_name[dashes - line - 1] = '\0';
Daniel Vetter73c21042011-10-11 13:14:02 +0200359
Ben Widawskyafeb4312013-04-22 11:36:03 -0700360 if (num_rings == -1)
361 num_rings = head_ndx;
362
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700363 matched = sscanf(dashes, "--- gtt_offset = 0x%08x\n",
364 &new_gtt_offset);
365 if (matched == 1) {
Damien Lespiau1d2ef952013-12-16 11:28:39 +0000366 decode(decode_ctx, is_batch, ring_name,
367 gtt_offset, data, &count);
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700368 gtt_offset = new_gtt_offset;
369 is_batch = 1;
370 free(ring_name);
371 ring_name = new_ring_name;
372 continue;
373 }
374
375 matched = sscanf(dashes, "--- ringbuffer = 0x%08x\n",
376 &new_gtt_offset);
377 if (matched == 1) {
Damien Lespiau1d2ef952013-12-16 11:28:39 +0000378 decode(decode_ctx, is_batch, ring_name,
379 gtt_offset, data, &count);
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700380 gtt_offset = new_gtt_offset;
381 is_batch = 0;
382 free(ring_name);
383 ring_name = new_ring_name;
384 continue;
385 }
386 }
387
388 matched = sscanf(line, "%08x : %08x", &offset, &value);
389 if (matched != 2) {
390 unsigned int reg;
391
392 /* display reg section is after the ringbuffers, don't mix them */
Damien Lespiau1d2ef952013-12-16 11:28:39 +0000393 decode(decode_ctx, is_batch, ring_name, gtt_offset,
394 data, &count);
Chris Wilson9eb4de12010-02-12 13:28:40 +0000395
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700396 printf("%s", line);
397
398 matched = sscanf(line, "PCI ID: 0x%04x\n", &reg);
399 if (matched == 0)
400 matched = sscanf(line, " PCI ID: 0x%04x\n", &reg);
401 if (matched == 0) {
402 const char *pci_id_start = strstr(line, "PCI ID");
403 if (pci_id_start)
404 matched = sscanf(pci_id_start, "PCI ID: 0x%04x\n", &reg);
Chris Wilson98eb5a52011-01-09 13:26:50 +0000405 }
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700406 if (matched == 1) {
407 devid = reg;
408 printf("Detected GEN%i chipset\n",
409 intel_gen(devid));
410
411 decode_ctx = drm_intel_decode_context_alloc(devid);
412 }
413
Mika Kuoppalaedee9522013-07-12 17:02:04 +0300414 matched = sscanf(line, " CTL: 0x%08x\n", &reg);
415 if (matched == 1)
416 ring_length = print_ctl(reg);
417
Ben Widawskyafeb4312013-04-22 11:36:03 -0700418 matched = sscanf(line, " HEAD: 0x%08x\n", &reg);
419 if (matched == 1) {
Chris Wilsonb5109e62014-01-23 21:50:36 +0000420 head[num_rings++] = print_head(reg);
Ben Widawskyafeb4312013-04-22 11:36:03 -0700421 }
422
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700423 matched = sscanf(line, " ACTHD: 0x%08x\n", &reg);
Mika Kuoppalaedee9522013-07-12 17:02:04 +0300424 if (matched == 1) {
425 print_acthd(reg, ring_length);
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700426 drm_intel_decode_set_head_tail(decode_ctx, reg, 0xffffffff);
Mika Kuoppalaedee9522013-07-12 17:02:04 +0300427 }
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700428
429 matched = sscanf(line, " PGTBL_ER: 0x%08x\n", &reg);
430 if (matched == 1 && reg)
431 print_pgtbl_err(reg, devid);
432
433 matched = sscanf(line, " INSTDONE: 0x%08x\n", &reg);
434 if (matched == 1)
435 print_instdone(devid, reg, -1);
436
437 matched = sscanf(line, " INSTDONE1: 0x%08x\n", &reg);
438 if (matched == 1)
439 print_instdone(devid, -1, reg);
440
441 matched = sscanf(line, " fence[%i] = %Lx\n", &reg, &fence);
442 if (matched == 2)
443 print_fence(devid, fence);
444
Chris Wilson98eb5a52011-01-09 13:26:50 +0000445 continue;
446 }
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700447
448 count++;
449
450 if (count > data_size) {
451 data_size = data_size ? data_size * 2 : 1024;
452 data = realloc(data, data_size * sizeof (uint32_t));
453 if (data == NULL) {
454 fprintf(stderr, "Out of memory.\n");
455 exit(1);
456 }
457 }
458
459 data[count-1] = value;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000460 }
461
Damien Lespiau1d2ef952013-12-16 11:28:39 +0000462 decode(decode_ctx, is_batch, ring_name, gtt_offset, data, &count);
Chris Wilson9eb4de12010-02-12 13:28:40 +0000463
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700464 free(data);
465 free(line);
466 free(ring_name);
Chris Wilson9eb4de12010-02-12 13:28:40 +0000467}
468
469int
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700470main(int argc, char *argv[])
Chris Wilson9eb4de12010-02-12 13:28:40 +0000471{
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700472 FILE *file;
473 const char *path;
474 char *filename = NULL;
475 struct stat st;
476 int error;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000477
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700478 if (argc > 2) {
479 fprintf(stderr,
480 "intel_gpu_decode: Parse an Intel GPU i915_error_state\n"
481 "Usage:\n"
482 "\t%s [<file>]\n"
483 "\n"
484 "With no arguments, debugfs-dri-directory is probed for in "
485 "/debug and \n"
486 "/sys/kernel/debug. Otherwise, it may be "
487 "specified. If a file is given,\n"
488 "it is parsed as an GPU dump in the format of "
489 "/debug/dri/0/i915_error_state.\n",
490 argv[0]);
491 return 1;
492 }
Chris Wilson9eb4de12010-02-12 13:28:40 +0000493
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700494 if (argc == 1) {
495 if (isatty(0)) {
Chris Wilsondbbf2e92013-08-07 23:41:54 +0100496 path = "/sys/class/drm/card0/error";
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700497 error = stat(path, &st);
498 if (error != 0) {
Chris Wilsondbbf2e92013-08-07 23:41:54 +0100499 path = "/debug/dri";
500 error = stat(path, &st);
501 }
502 if (error != 0) {
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700503 path = "/sys/kernel/debug/dri";
504 error = stat(path, &st);
Chris Wilsondbbf2e92013-08-07 23:41:54 +0100505 }
506 if (error != 0) {
507 errx(1,
508 "Couldn't find i915 debugfs directory.\n\n"
509 "Is debugfs mounted? You might try mounting it with a command such as:\n\n"
510 "\tsudo mount -t debugfs debugfs /sys/kernel/debug\n");
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700511 }
512 } else {
513 read_data_file(stdin);
514 exit(0);
Chris Wilsona3a78632010-12-01 21:51:59 +0000515 }
Chris Wilsona3a78632010-12-01 21:51:59 +0000516 } else {
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700517 path = argv[1];
518 error = stat(path, &st);
519 if (error != 0) {
520 fprintf(stderr, "Error opening %s: %s\n",
521 path, strerror(errno));
522 exit(1);
523 }
Chris Wilson9eb4de12010-02-12 13:28:40 +0000524 }
Chris Wilson9eb4de12010-02-12 13:28:40 +0000525
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700526 if (S_ISDIR(st.st_mode)) {
527 int ret;
Imre Deak5efd3d32012-10-10 16:04:39 +0300528
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700529 ret = asprintf(&filename, "%s/i915_error_state", path);
Imre Deak5efd3d32012-10-10 16:04:39 +0300530 assert(ret > 0);
Chris Wilson68a95f02011-01-25 16:34:08 +0000531 file = fopen(filename, "r");
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700532 if (!file) {
533 int minor;
534 for (minor = 0; minor < 64; minor++) {
535 free(filename);
536 ret = asprintf(&filename, "%s/%d/i915_error_state", path, minor);
537 assert(ret > 0);
Chris Wilson9eb4de12010-02-12 13:28:40 +0000538
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700539 file = fopen(filename, "r");
540 if (file)
541 break;
542 }
543 }
544 if (!file) {
545 fprintf(stderr, "Failed to find i915_error_state beneath %s\n",
546 path);
547 exit (1);
548 }
549 } else {
550 file = fopen(path, "r");
551 if (!file) {
552 fprintf(stderr, "Failed to open %s: %s\n",
553 path, strerror(errno));
554 exit (1);
555 }
556 }
Chris Wilson68a95f02011-01-25 16:34:08 +0000557
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700558 read_data_file(file);
559 fclose(file);
Chris Wilsona3a78632010-12-01 21:51:59 +0000560
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700561 if (filename != path)
562 free(filename);
563
564 return 0;
Chris Wilson9eb4de12010-02-12 13:28:40 +0000565}
Ben Widawsky155aa1e2013-04-22 11:07:35 -0700566
567/* vim: set ts=8 sw=8 tw=0 noet :*/