Merge remote-tracking branch 'mesa-public/master' into vulkan
[mesa.git] / src / gallium / drivers / radeonsi / si_debug.c
1 /*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Marek Olšák <maraeo@gmail.com>
25 */
26
27 #include "si_pipe.h"
28 #include "si_shader.h"
29 #include "sid.h"
30 #include "sid_tables.h"
31
32
33 static void si_dump_shader(struct si_shader_selector *sel, const char *name,
34 FILE *f)
35 {
36 if (!sel || !sel->current)
37 return;
38
39 fprintf(f, "%s shader disassembly:\n", name);
40 si_dump_shader_key(sel->type, &sel->current->key, f);
41 fprintf(f, "%s\n\n", sel->current->binary.disasm_string);
42 }
43
44 /* Parsed IBs are difficult to read without colors. Use "less -R file" to
45 * read them, or use "aha -b -f file" to convert them to html.
46 */
47 #define COLOR_RESET "\033[0m"
48 #define COLOR_RED "\033[31m"
49 #define COLOR_GREEN "\033[1;32m"
50 #define COLOR_YELLOW "\033[1;33m"
51 #define COLOR_CYAN "\033[1;36m"
52
53 #define INDENT_PKT 8
54
55 static void print_spaces(FILE *f, unsigned num)
56 {
57 fprintf(f, "%*s", num, "");
58 }
59
60 static void print_value(FILE *file, uint32_t value, int bits)
61 {
62 /* Guess if it's int or float */
63 if (value <= (1 << 15))
64 fprintf(file, "%u\n", value);
65 else {
66 float f = uif(value);
67
68 if (fabs(f) < 100000 && f*10 == floor(f*10))
69 fprintf(file, "%.1ff\n", f);
70 else
71 /* Don't print more leading zeros than there are bits. */
72 fprintf(file, "0x%0*x\n", bits / 4, value);
73 }
74 }
75
76 static void print_named_value(FILE *file, const char *name, uint32_t value,
77 int bits)
78 {
79 print_spaces(file, INDENT_PKT);
80 fprintf(file, COLOR_YELLOW "%s" COLOR_RESET " <- ", name);
81 print_value(file, value, bits);
82 }
83
84 static void si_dump_reg(FILE *file, unsigned offset, uint32_t value,
85 uint32_t field_mask)
86 {
87 int r, f;
88
89 for (r = 0; r < ARRAY_SIZE(reg_table); r++) {
90 const struct si_reg *reg = &reg_table[r];
91
92 if (reg->offset == offset) {
93 bool first_field = true;
94
95 print_spaces(file, INDENT_PKT);
96 fprintf(file, COLOR_YELLOW "%s" COLOR_RESET " <- ",
97 reg->name);
98
99 if (!reg->num_fields) {
100 print_value(file, value, 32);
101 return;
102 }
103
104 for (f = 0; f < reg->num_fields; f++) {
105 const struct si_field *field = &reg->fields[f];
106 uint32_t val = (value & field->mask) >>
107 (ffs(field->mask) - 1);
108
109 if (!(field->mask & field_mask))
110 continue;
111
112 /* Indent the field. */
113 if (!first_field)
114 print_spaces(file,
115 INDENT_PKT + strlen(reg->name) + 4);
116
117 /* Print the field. */
118 fprintf(file, "%s = ", field->name);
119
120 if (val < field->num_values && field->values[val])
121 fprintf(file, "%s\n", field->values[val]);
122 else
123 print_value(file, val,
124 util_bitcount(field->mask));
125
126 first_field = false;
127 }
128 return;
129 }
130 }
131
132 fprintf(file, COLOR_YELLOW "0x%05x" COLOR_RESET " = 0x%08x", offset, value);
133 }
134
135 static void si_parse_set_reg_packet(FILE *f, uint32_t *ib, unsigned count,
136 unsigned reg_offset)
137 {
138 unsigned reg = (ib[1] << 2) + reg_offset;
139 int i;
140
141 for (i = 0; i < count; i++)
142 si_dump_reg(f, reg + i*4, ib[2+i], ~0);
143 }
144
145 static uint32_t *si_parse_packet3(FILE *f, uint32_t *ib, int *num_dw,
146 int trace_id)
147 {
148 unsigned count = PKT_COUNT_G(ib[0]);
149 unsigned op = PKT3_IT_OPCODE_G(ib[0]);
150 const char *predicate = PKT3_PREDICATE(ib[0]) ? "(predicate)" : "";
151 int i;
152
153 /* Print the name first. */
154 for (i = 0; i < ARRAY_SIZE(packet3_table); i++)
155 if (packet3_table[i].op == op)
156 break;
157
158 if (i < ARRAY_SIZE(packet3_table))
159 if (op == PKT3_SET_CONTEXT_REG ||
160 op == PKT3_SET_CONFIG_REG ||
161 op == PKT3_SET_UCONFIG_REG ||
162 op == PKT3_SET_SH_REG)
163 fprintf(f, COLOR_CYAN "%s%s" COLOR_CYAN ":\n",
164 packet3_table[i].name, predicate);
165 else
166 fprintf(f, COLOR_GREEN "%s%s" COLOR_RESET ":\n",
167 packet3_table[i].name, predicate);
168 else
169 fprintf(f, COLOR_RED "PKT3_UNKNOWN 0x%x%s" COLOR_RESET ":\n",
170 op, predicate);
171
172 /* Print the contents. */
173 switch (op) {
174 case PKT3_SET_CONTEXT_REG:
175 si_parse_set_reg_packet(f, ib, count, SI_CONTEXT_REG_OFFSET);
176 break;
177 case PKT3_SET_CONFIG_REG:
178 si_parse_set_reg_packet(f, ib, count, SI_CONFIG_REG_OFFSET);
179 break;
180 case PKT3_SET_UCONFIG_REG:
181 si_parse_set_reg_packet(f, ib, count, CIK_UCONFIG_REG_OFFSET);
182 break;
183 case PKT3_SET_SH_REG:
184 si_parse_set_reg_packet(f, ib, count, SI_SH_REG_OFFSET);
185 break;
186 case PKT3_DRAW_PREAMBLE:
187 si_dump_reg(f, R_030908_VGT_PRIMITIVE_TYPE, ib[1], ~0);
188 si_dump_reg(f, R_028AA8_IA_MULTI_VGT_PARAM, ib[2], ~0);
189 si_dump_reg(f, R_028B58_VGT_LS_HS_CONFIG, ib[3], ~0);
190 break;
191 case PKT3_ACQUIRE_MEM:
192 si_dump_reg(f, R_0301F0_CP_COHER_CNTL, ib[1], ~0);
193 si_dump_reg(f, R_0301F4_CP_COHER_SIZE, ib[2], ~0);
194 si_dump_reg(f, R_030230_CP_COHER_SIZE_HI, ib[3], ~0);
195 si_dump_reg(f, R_0301F8_CP_COHER_BASE, ib[4], ~0);
196 si_dump_reg(f, R_0301E4_CP_COHER_BASE_HI, ib[5], ~0);
197 print_named_value(f, "POLL_INTERVAL", ib[6], 16);
198 break;
199 case PKT3_SURFACE_SYNC:
200 si_dump_reg(f, R_0085F0_CP_COHER_CNTL, ib[1], ~0);
201 si_dump_reg(f, R_0085F4_CP_COHER_SIZE, ib[2], ~0);
202 si_dump_reg(f, R_0085F8_CP_COHER_BASE, ib[3], ~0);
203 print_named_value(f, "POLL_INTERVAL", ib[4], 16);
204 break;
205 case PKT3_EVENT_WRITE:
206 si_dump_reg(f, R_028A90_VGT_EVENT_INITIATOR, ib[1],
207 S_028A90_EVENT_TYPE(~0));
208 print_named_value(f, "EVENT_INDEX", (ib[1] >> 8) & 0xf, 4);
209 print_named_value(f, "INV_L2", (ib[1] >> 20) & 0x1, 1);
210 if (count > 0) {
211 print_named_value(f, "ADDRESS_LO", ib[2], 32);
212 print_named_value(f, "ADDRESS_HI", ib[3], 16);
213 }
214 break;
215 case PKT3_DRAW_INDEX_AUTO:
216 si_dump_reg(f, R_030930_VGT_NUM_INDICES, ib[1], ~0);
217 si_dump_reg(f, R_0287F0_VGT_DRAW_INITIATOR, ib[2], ~0);
218 break;
219 case PKT3_DRAW_INDEX_2:
220 si_dump_reg(f, R_028A78_VGT_DMA_MAX_SIZE, ib[1], ~0);
221 si_dump_reg(f, R_0287E8_VGT_DMA_BASE, ib[2], ~0);
222 si_dump_reg(f, R_0287E4_VGT_DMA_BASE_HI, ib[3], ~0);
223 si_dump_reg(f, R_030930_VGT_NUM_INDICES, ib[4], ~0);
224 si_dump_reg(f, R_0287F0_VGT_DRAW_INITIATOR, ib[5], ~0);
225 break;
226 case PKT3_INDEX_TYPE:
227 si_dump_reg(f, R_028A7C_VGT_DMA_INDEX_TYPE, ib[1], ~0);
228 break;
229 case PKT3_NUM_INSTANCES:
230 si_dump_reg(f, R_030934_VGT_NUM_INSTANCES, ib[1], ~0);
231 break;
232 case PKT3_WRITE_DATA:
233 si_dump_reg(f, R_370_CONTROL, ib[1], ~0);
234 si_dump_reg(f, R_371_DST_ADDR_LO, ib[2], ~0);
235 si_dump_reg(f, R_372_DST_ADDR_HI, ib[3], ~0);
236 for (i = 2; i < count; i++) {
237 print_spaces(f, INDENT_PKT);
238 fprintf(f, "0x%08x\n", ib[2+i]);
239 }
240 break;
241 case PKT3_CP_DMA:
242 si_dump_reg(f, R_410_CP_DMA_WORD0, ib[1], ~0);
243 si_dump_reg(f, R_411_CP_DMA_WORD1, ib[2], ~0);
244 si_dump_reg(f, R_412_CP_DMA_WORD2, ib[3], ~0);
245 si_dump_reg(f, R_413_CP_DMA_WORD3, ib[4], ~0);
246 si_dump_reg(f, R_414_COMMAND, ib[5], ~0);
247 break;
248 case PKT3_DMA_DATA:
249 si_dump_reg(f, R_500_DMA_DATA_WORD0, ib[1], ~0);
250 si_dump_reg(f, R_501_SRC_ADDR_LO, ib[2], ~0);
251 si_dump_reg(f, R_502_SRC_ADDR_HI, ib[3], ~0);
252 si_dump_reg(f, R_503_DST_ADDR_LO, ib[4], ~0);
253 si_dump_reg(f, R_504_DST_ADDR_HI, ib[5], ~0);
254 si_dump_reg(f, R_414_COMMAND, ib[6], ~0);
255 break;
256 case PKT3_NOP:
257 if (ib[0] == 0xffff1000) {
258 count = -1; /* One dword NOP. */
259 break;
260 } else if (count == 0 && SI_IS_TRACE_POINT(ib[1])) {
261 unsigned packet_id = SI_GET_TRACE_POINT_ID(ib[1]);
262
263 print_spaces(f, INDENT_PKT);
264 fprintf(f, COLOR_RED "Trace point ID: %u\n", packet_id);
265
266 if (trace_id == -1)
267 break; /* tracing was disabled */
268
269 print_spaces(f, INDENT_PKT);
270 if (packet_id < trace_id)
271 fprintf(f, COLOR_RED
272 "This trace point was reached by the CP."
273 COLOR_RESET "\n");
274 else if (packet_id == trace_id)
275 fprintf(f, COLOR_RED
276 "!!!!! This is the last trace point that "
277 "was reached by the CP !!!!!"
278 COLOR_RESET "\n");
279 else if (packet_id+1 == trace_id)
280 fprintf(f, COLOR_RED
281 "!!!!! This is the first trace point that "
282 "was NOT been reached by the CP !!!!!"
283 COLOR_RESET "\n");
284 else
285 fprintf(f, COLOR_RED
286 "!!!!! This trace point was NOT reached "
287 "by the CP !!!!!"
288 COLOR_RESET "\n");
289 break;
290 }
291 /* fall through, print all dwords */
292 default:
293 for (i = 0; i < count+1; i++) {
294 print_spaces(f, INDENT_PKT);
295 fprintf(f, "0x%08x\n", ib[1+i]);
296 }
297 }
298
299 ib += count + 2;
300 *num_dw -= count + 2;
301 return ib;
302 }
303
304 /**
305 * Parse and print an IB into a file.
306 *
307 * \param f file
308 * \param ib IB
309 * \param num_dw size of the IB
310 * \param chip_class chip class
311 * \param trace_id the last trace ID that is known to have been reached
312 * and executed by the CP, typically read from a buffer
313 */
314 static void si_parse_ib(FILE *f, uint32_t *ib, int num_dw, int trace_id)
315 {
316 fprintf(f, "------------------ IB begin ------------------\n");
317
318 while (num_dw > 0) {
319 unsigned type = PKT_TYPE_G(ib[0]);
320
321 switch (type) {
322 case 3:
323 ib = si_parse_packet3(f, ib, &num_dw, trace_id);
324 break;
325 case 2:
326 /* type-2 nop */
327 if (ib[0] == 0x80000000) {
328 fprintf(f, COLOR_GREEN "NOP (type 2)" COLOR_RESET "\n");
329 ib++;
330 break;
331 }
332 /* fall through */
333 default:
334 fprintf(f, "Unknown packet type %i\n", type);
335 return;
336 }
337 }
338
339 fprintf(f, "------------------- IB end -------------------\n");
340 if (num_dw < 0) {
341 printf("Packet ends after the end of IB.\n");
342 exit(0);
343 }
344 }
345
346 static void si_dump_mmapped_reg(struct si_context *sctx, FILE *f,
347 unsigned offset)
348 {
349 struct radeon_winsys *ws = sctx->b.ws;
350 uint32_t value;
351
352 if (ws->read_registers(ws, offset, 1, &value))
353 si_dump_reg(f, offset, value, ~0);
354 }
355
356 static void si_dump_debug_registers(struct si_context *sctx, FILE *f)
357 {
358 if (sctx->screen->b.info.drm_major == 2 &&
359 sctx->screen->b.info.drm_minor < 42)
360 return; /* no radeon support */
361
362 fprintf(f, "Memory-mapped registers:\n");
363 si_dump_mmapped_reg(sctx, f, R_008010_GRBM_STATUS);
364
365 /* No other registers can be read on DRM < 3.1.0. */
366 if (sctx->screen->b.info.drm_major < 3 ||
367 sctx->screen->b.info.drm_minor < 1) {
368 fprintf(f, "\n");
369 return;
370 }
371
372 si_dump_mmapped_reg(sctx, f, R_008008_GRBM_STATUS2);
373 si_dump_mmapped_reg(sctx, f, R_008014_GRBM_STATUS_SE0);
374 si_dump_mmapped_reg(sctx, f, R_008018_GRBM_STATUS_SE1);
375 si_dump_mmapped_reg(sctx, f, R_008038_GRBM_STATUS_SE2);
376 si_dump_mmapped_reg(sctx, f, R_00803C_GRBM_STATUS_SE3);
377 si_dump_mmapped_reg(sctx, f, R_00D034_SDMA0_STATUS_REG);
378 si_dump_mmapped_reg(sctx, f, R_00D834_SDMA1_STATUS_REG);
379 si_dump_mmapped_reg(sctx, f, R_000E50_SRBM_STATUS);
380 si_dump_mmapped_reg(sctx, f, R_000E4C_SRBM_STATUS2);
381 si_dump_mmapped_reg(sctx, f, R_000E54_SRBM_STATUS3);
382 si_dump_mmapped_reg(sctx, f, R_008680_CP_STAT);
383 si_dump_mmapped_reg(sctx, f, R_008674_CP_STALLED_STAT1);
384 si_dump_mmapped_reg(sctx, f, R_008678_CP_STALLED_STAT2);
385 si_dump_mmapped_reg(sctx, f, R_008670_CP_STALLED_STAT3);
386 si_dump_mmapped_reg(sctx, f, R_008210_CP_CPC_STATUS);
387 si_dump_mmapped_reg(sctx, f, R_008214_CP_CPC_BUSY_STAT);
388 si_dump_mmapped_reg(sctx, f, R_008218_CP_CPC_STALLED_STAT1);
389 si_dump_mmapped_reg(sctx, f, R_00821C_CP_CPF_STATUS);
390 si_dump_mmapped_reg(sctx, f, R_008220_CP_CPF_BUSY_STAT);
391 si_dump_mmapped_reg(sctx, f, R_008224_CP_CPF_STALLED_STAT1);
392 fprintf(f, "\n");
393 }
394
395 static void si_dump_debug_state(struct pipe_context *ctx, FILE *f,
396 unsigned flags)
397 {
398 struct si_context *sctx = (struct si_context*)ctx;
399
400 if (flags & PIPE_DEBUG_DEVICE_IS_HUNG)
401 si_dump_debug_registers(sctx, f);
402
403 si_dump_shader(sctx->vs_shader, "Vertex", f);
404 si_dump_shader(sctx->tcs_shader, "Tessellation control", f);
405 si_dump_shader(sctx->tes_shader, "Tessellation evaluation", f);
406 si_dump_shader(sctx->gs_shader, "Geometry", f);
407 si_dump_shader(sctx->ps_shader, "Fragment", f);
408
409 if (sctx->last_ib) {
410 int last_trace_id = -1;
411
412 if (sctx->last_trace_buf) {
413 /* We are expecting that the ddebug pipe has already
414 * waited for the context, so this buffer should be idle.
415 * If the GPU is hung, there is no point in waiting for it.
416 */
417 uint32_t *map =
418 sctx->b.ws->buffer_map(sctx->last_trace_buf->cs_buf,
419 NULL,
420 PIPE_TRANSFER_UNSYNCHRONIZED |
421 PIPE_TRANSFER_READ);
422 if (map)
423 last_trace_id = *map;
424 }
425
426 si_parse_ib(f, sctx->last_ib, sctx->last_ib_dw_size,
427 last_trace_id);
428 free(sctx->last_ib); /* dump only once */
429 sctx->last_ib = NULL;
430 r600_resource_reference(&sctx->last_trace_buf, NULL);
431 }
432
433 fprintf(f, "Done.\n");
434 }
435
436 void si_init_debug_functions(struct si_context *sctx)
437 {
438 sctx->b.b.dump_debug_state = si_dump_debug_state;
439 }