Home | History | Annotate | Download | only in radeonsi
      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 Olk <maraeo (at) gmail.com>
     25  */
     26 
     27 #include "si_pipe.h"
     28 #include "sid.h"
     29 #include "sid_tables.h"
     30 #include "radeon/radeon_elf_util.h"
     31 #include "ddebug/dd_util.h"
     32 #include "util/u_memory.h"
     33 #include "ac_debug.h"
     34 
     35 DEBUG_GET_ONCE_OPTION(replace_shaders, "RADEON_REPLACE_SHADERS", NULL)
     36 
     37 static void si_dump_shader(struct si_screen *sscreen,
     38 			   struct si_shader_ctx_state *state, FILE *f)
     39 {
     40 	struct si_shader *current = state->current;
     41 
     42 	if (!state->cso || !current)
     43 		return;
     44 
     45 	if (current->shader_log)
     46 		fwrite(current->shader_log, current->shader_log_size, 1, f);
     47 	else
     48 		si_shader_dump(sscreen, state->current, NULL,
     49 			       state->cso->info.processor, f, false);
     50 }
     51 
     52 /**
     53  * Shader compiles can be overridden with arbitrary ELF objects by setting
     54  * the environment variable RADEON_REPLACE_SHADERS=num1:filename1[;num2:filename2]
     55  */
     56 bool si_replace_shader(unsigned num, struct radeon_shader_binary *binary)
     57 {
     58 	const char *p = debug_get_option_replace_shaders();
     59 	const char *semicolon;
     60 	char *copy = NULL;
     61 	FILE *f;
     62 	long filesize, nread;
     63 	char *buf = NULL;
     64 	bool replaced = false;
     65 
     66 	if (!p)
     67 		return false;
     68 
     69 	while (*p) {
     70 		unsigned long i;
     71 		char *endp;
     72 		i = strtoul(p, &endp, 0);
     73 
     74 		p = endp;
     75 		if (*p != ':') {
     76 			fprintf(stderr, "RADEON_REPLACE_SHADERS formatted badly.\n");
     77 			exit(1);
     78 		}
     79 		++p;
     80 
     81 		if (i == num)
     82 			break;
     83 
     84 		p = strchr(p, ';');
     85 		if (!p)
     86 			return false;
     87 		++p;
     88 	}
     89 	if (!*p)
     90 		return false;
     91 
     92 	semicolon = strchr(p, ';');
     93 	if (semicolon) {
     94 		p = copy = strndup(p, semicolon - p);
     95 		if (!copy) {
     96 			fprintf(stderr, "out of memory\n");
     97 			return false;
     98 		}
     99 	}
    100 
    101 	fprintf(stderr, "radeonsi: replace shader %u by %s\n", num, p);
    102 
    103 	f = fopen(p, "r");
    104 	if (!f) {
    105 		perror("radeonsi: failed to open file");
    106 		goto out_free;
    107 	}
    108 
    109 	if (fseek(f, 0, SEEK_END) != 0)
    110 		goto file_error;
    111 
    112 	filesize = ftell(f);
    113 	if (filesize < 0)
    114 		goto file_error;
    115 
    116 	if (fseek(f, 0, SEEK_SET) != 0)
    117 		goto file_error;
    118 
    119 	buf = MALLOC(filesize);
    120 	if (!buf) {
    121 		fprintf(stderr, "out of memory\n");
    122 		goto out_close;
    123 	}
    124 
    125 	nread = fread(buf, 1, filesize, f);
    126 	if (nread != filesize)
    127 		goto file_error;
    128 
    129 	radeon_elf_read(buf, filesize, binary);
    130 	replaced = true;
    131 
    132 out_close:
    133 	fclose(f);
    134 out_free:
    135 	FREE(buf);
    136 	free(copy);
    137 	return replaced;
    138 
    139 file_error:
    140 	perror("radeonsi: reading shader");
    141 	goto out_close;
    142 }
    143 
    144 /* Parsed IBs are difficult to read without colors. Use "less -R file" to
    145  * read them, or use "aha -b -f file" to convert them to html.
    146  */
    147 #define COLOR_RESET	"\033[0m"
    148 #define COLOR_RED	"\033[31m"
    149 #define COLOR_GREEN	"\033[1;32m"
    150 #define COLOR_YELLOW	"\033[1;33m"
    151 #define COLOR_CYAN	"\033[1;36m"
    152 
    153 static void si_dump_mmapped_reg(struct si_context *sctx, FILE *f,
    154 				unsigned offset)
    155 {
    156 	struct radeon_winsys *ws = sctx->b.ws;
    157 	uint32_t value;
    158 
    159 	if (ws->read_registers(ws, offset, 1, &value))
    160 		ac_dump_reg(f, offset, value, ~0);
    161 }
    162 
    163 static void si_dump_debug_registers(struct si_context *sctx, FILE *f)
    164 {
    165 	if (sctx->screen->b.info.drm_major == 2 &&
    166 	    sctx->screen->b.info.drm_minor < 42)
    167 		return; /* no radeon support */
    168 
    169 	fprintf(f, "Memory-mapped registers:\n");
    170 	si_dump_mmapped_reg(sctx, f, R_008010_GRBM_STATUS);
    171 
    172 	/* No other registers can be read on DRM < 3.1.0. */
    173 	if (sctx->screen->b.info.drm_major < 3 ||
    174 	    sctx->screen->b.info.drm_minor < 1) {
    175 		fprintf(f, "\n");
    176 		return;
    177 	}
    178 
    179 	si_dump_mmapped_reg(sctx, f, R_008008_GRBM_STATUS2);
    180 	si_dump_mmapped_reg(sctx, f, R_008014_GRBM_STATUS_SE0);
    181 	si_dump_mmapped_reg(sctx, f, R_008018_GRBM_STATUS_SE1);
    182 	si_dump_mmapped_reg(sctx, f, R_008038_GRBM_STATUS_SE2);
    183 	si_dump_mmapped_reg(sctx, f, R_00803C_GRBM_STATUS_SE3);
    184 	si_dump_mmapped_reg(sctx, f, R_00D034_SDMA0_STATUS_REG);
    185 	si_dump_mmapped_reg(sctx, f, R_00D834_SDMA1_STATUS_REG);
    186 	si_dump_mmapped_reg(sctx, f, R_000E50_SRBM_STATUS);
    187 	si_dump_mmapped_reg(sctx, f, R_000E4C_SRBM_STATUS2);
    188 	si_dump_mmapped_reg(sctx, f, R_000E54_SRBM_STATUS3);
    189 	si_dump_mmapped_reg(sctx, f, R_008680_CP_STAT);
    190 	si_dump_mmapped_reg(sctx, f, R_008674_CP_STALLED_STAT1);
    191 	si_dump_mmapped_reg(sctx, f, R_008678_CP_STALLED_STAT2);
    192 	si_dump_mmapped_reg(sctx, f, R_008670_CP_STALLED_STAT3);
    193 	si_dump_mmapped_reg(sctx, f, R_008210_CP_CPC_STATUS);
    194 	si_dump_mmapped_reg(sctx, f, R_008214_CP_CPC_BUSY_STAT);
    195 	si_dump_mmapped_reg(sctx, f, R_008218_CP_CPC_STALLED_STAT1);
    196 	si_dump_mmapped_reg(sctx, f, R_00821C_CP_CPF_STATUS);
    197 	si_dump_mmapped_reg(sctx, f, R_008220_CP_CPF_BUSY_STAT);
    198 	si_dump_mmapped_reg(sctx, f, R_008224_CP_CPF_STALLED_STAT1);
    199 	fprintf(f, "\n");
    200 }
    201 
    202 static void si_dump_last_ib(struct si_context *sctx, FILE *f)
    203 {
    204 	int last_trace_id = -1;
    205 
    206 	if (!sctx->last_gfx.ib)
    207 		return;
    208 
    209 	if (sctx->last_trace_buf) {
    210 		/* We are expecting that the ddebug pipe has already
    211 		 * waited for the context, so this buffer should be idle.
    212 		 * If the GPU is hung, there is no point in waiting for it.
    213 		 */
    214 		uint32_t *map = sctx->b.ws->buffer_map(sctx->last_trace_buf->buf,
    215 						       NULL,
    216 						       PIPE_TRANSFER_UNSYNCHRONIZED |
    217 						       PIPE_TRANSFER_READ);
    218 		if (map)
    219 			last_trace_id = *map;
    220 	}
    221 
    222 	if (sctx->init_config)
    223 		ac_parse_ib(f, sctx->init_config->pm4, sctx->init_config->ndw,
    224 			    -1, "IB2: Init config", sctx->b.chip_class,
    225 			    NULL, NULL);
    226 
    227 	if (sctx->init_config_gs_rings)
    228 		ac_parse_ib(f, sctx->init_config_gs_rings->pm4,
    229 			    sctx->init_config_gs_rings->ndw,
    230 			    -1, "IB2: Init GS rings", sctx->b.chip_class,
    231 			    NULL, NULL);
    232 
    233 	ac_parse_ib(f, sctx->last_gfx.ib, sctx->last_gfx.num_dw,
    234 		    last_trace_id, "IB", sctx->b.chip_class,
    235 		     NULL, NULL);
    236 }
    237 
    238 static const char *priority_to_string(enum radeon_bo_priority priority)
    239 {
    240 #define ITEM(x) [RADEON_PRIO_##x] = #x
    241 	static const char *table[64] = {
    242 		ITEM(FENCE),
    243 	        ITEM(TRACE),
    244 	        ITEM(SO_FILLED_SIZE),
    245 	        ITEM(QUERY),
    246 	        ITEM(IB1),
    247 	        ITEM(IB2),
    248 	        ITEM(DRAW_INDIRECT),
    249 	        ITEM(INDEX_BUFFER),
    250 	        ITEM(VCE),
    251 	        ITEM(UVD),
    252 	        ITEM(SDMA_BUFFER),
    253 	        ITEM(SDMA_TEXTURE),
    254 		ITEM(CP_DMA),
    255 	        ITEM(CONST_BUFFER),
    256 	        ITEM(DESCRIPTORS),
    257 	        ITEM(BORDER_COLORS),
    258 	        ITEM(SAMPLER_BUFFER),
    259 	        ITEM(VERTEX_BUFFER),
    260 	        ITEM(SHADER_RW_BUFFER),
    261 	        ITEM(COMPUTE_GLOBAL),
    262 	        ITEM(SAMPLER_TEXTURE),
    263 	        ITEM(SHADER_RW_IMAGE),
    264 	        ITEM(SAMPLER_TEXTURE_MSAA),
    265 	        ITEM(COLOR_BUFFER),
    266 	        ITEM(DEPTH_BUFFER),
    267 	        ITEM(COLOR_BUFFER_MSAA),
    268 	        ITEM(DEPTH_BUFFER_MSAA),
    269 	        ITEM(CMASK),
    270 	        ITEM(DCC),
    271 	        ITEM(HTILE),
    272 		ITEM(SHADER_BINARY),
    273 		ITEM(SHADER_RINGS),
    274 		ITEM(SCRATCH_BUFFER),
    275 	};
    276 #undef ITEM
    277 
    278 	assert(priority < ARRAY_SIZE(table));
    279 	return table[priority];
    280 }
    281 
    282 static int bo_list_compare_va(const struct radeon_bo_list_item *a,
    283 				   const struct radeon_bo_list_item *b)
    284 {
    285 	return a->vm_address < b->vm_address ? -1 :
    286 	       a->vm_address > b->vm_address ? 1 : 0;
    287 }
    288 
    289 static void si_dump_bo_list(struct si_context *sctx,
    290 			    const struct radeon_saved_cs *saved, FILE *f)
    291 {
    292 	unsigned i,j;
    293 
    294 	if (!saved->bo_list)
    295 		return;
    296 
    297 	/* Sort the list according to VM adddresses first. */
    298 	qsort(saved->bo_list, saved->bo_count,
    299 	      sizeof(saved->bo_list[0]), (void*)bo_list_compare_va);
    300 
    301 	fprintf(f, "Buffer list (in units of pages = 4kB):\n"
    302 		COLOR_YELLOW "        Size    VM start page         "
    303 		"VM end page           Usage" COLOR_RESET "\n");
    304 
    305 	for (i = 0; i < saved->bo_count; i++) {
    306 		/* Note: Buffer sizes are expected to be aligned to 4k by the winsys. */
    307 		const unsigned page_size = sctx->b.screen->info.gart_page_size;
    308 		uint64_t va = saved->bo_list[i].vm_address;
    309 		uint64_t size = saved->bo_list[i].bo_size;
    310 		bool hit = false;
    311 
    312 		/* If there's unused virtual memory between 2 buffers, print it. */
    313 		if (i) {
    314 			uint64_t previous_va_end = saved->bo_list[i-1].vm_address +
    315 						   saved->bo_list[i-1].bo_size;
    316 
    317 			if (va > previous_va_end) {
    318 				fprintf(f, "  %10"PRIu64"    -- hole --\n",
    319 					(va - previous_va_end) / page_size);
    320 			}
    321 		}
    322 
    323 		/* Print the buffer. */
    324 		fprintf(f, "  %10"PRIu64"    0x%013"PRIX64"       0x%013"PRIX64"       ",
    325 			size / page_size, va / page_size, (va + size) / page_size);
    326 
    327 		/* Print the usage. */
    328 		for (j = 0; j < 64; j++) {
    329 			if (!(saved->bo_list[i].priority_usage & (1llu << j)))
    330 				continue;
    331 
    332 			fprintf(f, "%s%s", !hit ? "" : ", ", priority_to_string(j));
    333 			hit = true;
    334 		}
    335 		fprintf(f, "\n");
    336 	}
    337 	fprintf(f, "\nNote: The holes represent memory not used by the IB.\n"
    338 		   "      Other buffers can still be allocated there.\n\n");
    339 }
    340 
    341 static void si_dump_framebuffer(struct si_context *sctx, FILE *f)
    342 {
    343 	struct pipe_framebuffer_state *state = &sctx->framebuffer.state;
    344 	struct r600_texture *rtex;
    345 	int i;
    346 
    347 	for (i = 0; i < state->nr_cbufs; i++) {
    348 		if (!state->cbufs[i])
    349 			continue;
    350 
    351 		rtex = (struct r600_texture*)state->cbufs[i]->texture;
    352 		fprintf(f, COLOR_YELLOW "Color buffer %i:" COLOR_RESET "\n", i);
    353 		r600_print_texture_info(rtex, f);
    354 		fprintf(f, "\n");
    355 	}
    356 
    357 	if (state->zsbuf) {
    358 		rtex = (struct r600_texture*)state->zsbuf->texture;
    359 		fprintf(f, COLOR_YELLOW "Depth-stencil buffer:" COLOR_RESET "\n");
    360 		r600_print_texture_info(rtex, f);
    361 		fprintf(f, "\n");
    362 	}
    363 }
    364 
    365 static void si_dump_descriptor_list(struct si_descriptors *desc,
    366 				    const char *shader_name,
    367 				    const char *elem_name,
    368 				    unsigned num_elements,
    369 				    FILE *f)
    370 {
    371 	unsigned i, j;
    372 	uint32_t *cpu_list = desc->list;
    373 	uint32_t *gpu_list = desc->gpu_list;
    374 	const char *list_note = "GPU list";
    375 
    376 	if (!gpu_list) {
    377 		gpu_list = cpu_list;
    378 		list_note = "CPU list";
    379 	}
    380 
    381 	for (i = 0; i < num_elements; i++) {
    382 		fprintf(f, COLOR_GREEN "%s%s slot %u (%s):" COLOR_RESET "\n",
    383 			shader_name, elem_name, i, list_note);
    384 
    385 		switch (desc->element_dw_size) {
    386 		case 4:
    387 			for (j = 0; j < 4; j++)
    388 				ac_dump_reg(f, R_008F00_SQ_BUF_RSRC_WORD0 + j*4,
    389 					    gpu_list[j], 0xffffffff);
    390 			break;
    391 		case 8:
    392 			for (j = 0; j < 8; j++)
    393 				ac_dump_reg(f, R_008F10_SQ_IMG_RSRC_WORD0 + j*4,
    394 					    gpu_list[j], 0xffffffff);
    395 
    396 			fprintf(f, COLOR_CYAN "    Buffer:" COLOR_RESET "\n");
    397 			for (j = 0; j < 4; j++)
    398 				ac_dump_reg(f, R_008F00_SQ_BUF_RSRC_WORD0 + j*4,
    399 					    gpu_list[4+j], 0xffffffff);
    400 			break;
    401 		case 16:
    402 			for (j = 0; j < 8; j++)
    403 				ac_dump_reg(f, R_008F10_SQ_IMG_RSRC_WORD0 + j*4,
    404 					    gpu_list[j], 0xffffffff);
    405 
    406 			fprintf(f, COLOR_CYAN "    Buffer:" COLOR_RESET "\n");
    407 			for (j = 0; j < 4; j++)
    408 				ac_dump_reg(f, R_008F00_SQ_BUF_RSRC_WORD0 + j*4,
    409 					    gpu_list[4+j], 0xffffffff);
    410 
    411 			fprintf(f, COLOR_CYAN "    FMASK:" COLOR_RESET "\n");
    412 			for (j = 0; j < 8; j++)
    413 				ac_dump_reg(f, R_008F10_SQ_IMG_RSRC_WORD0 + j*4,
    414 					    gpu_list[8+j], 0xffffffff);
    415 
    416 			fprintf(f, COLOR_CYAN "    Sampler state:" COLOR_RESET "\n");
    417 			for (j = 0; j < 4; j++)
    418 				ac_dump_reg(f, R_008F30_SQ_IMG_SAMP_WORD0 + j*4,
    419 					    gpu_list[12+j], 0xffffffff);
    420 			break;
    421 		}
    422 
    423 		if (memcmp(gpu_list, cpu_list, desc->element_dw_size * 4) != 0) {
    424 			fprintf(f, COLOR_RED "!!!!! This slot was corrupted in GPU memory !!!!!"
    425 				COLOR_RESET "\n");
    426 		}
    427 
    428 		fprintf(f, "\n");
    429 		gpu_list += desc->element_dw_size;
    430 		cpu_list += desc->element_dw_size;
    431 	}
    432 }
    433 
    434 static void si_dump_descriptors(struct si_context *sctx,
    435 				struct si_shader_ctx_state *state,
    436 				FILE *f)
    437 {
    438 	if (!state->cso || !state->current)
    439 		return;
    440 
    441 	unsigned type = state->cso->type;
    442 	const struct tgsi_shader_info *info = &state->cso->info;
    443 	struct si_descriptors *descs =
    444 		&sctx->descriptors[SI_DESCS_FIRST_SHADER +
    445 				   type * SI_NUM_SHADER_DESCS];
    446 	static const char *shader_name[] = {"VS", "PS", "GS", "TCS", "TES", "CS"};
    447 
    448 	static const char *elem_name[] = {
    449 		" - Constant buffer",
    450 		" - Shader buffer",
    451 		" - Sampler",
    452 		" - Image",
    453 	};
    454 	unsigned num_elements[] = {
    455 		util_last_bit(info->const_buffers_declared),
    456 		util_last_bit(info->shader_buffers_declared),
    457 		util_last_bit(info->samplers_declared),
    458 		util_last_bit(info->images_declared),
    459 	};
    460 
    461 	if (type == PIPE_SHADER_VERTEX) {
    462 		si_dump_descriptor_list(&sctx->vertex_buffers, shader_name[type],
    463 					" - Vertex buffer", info->num_inputs, f);
    464 	}
    465 
    466 	for (unsigned i = 0; i < SI_NUM_SHADER_DESCS; ++i, ++descs)
    467 		si_dump_descriptor_list(descs, shader_name[type], elem_name[i],
    468 					num_elements[i], f);
    469 }
    470 
    471 static void si_dump_debug_state(struct pipe_context *ctx, FILE *f,
    472 				unsigned flags)
    473 {
    474 	struct si_context *sctx = (struct si_context*)ctx;
    475 
    476 	if (flags & PIPE_DUMP_DEVICE_STATUS_REGISTERS)
    477 		si_dump_debug_registers(sctx, f);
    478 
    479 	if (flags & PIPE_DUMP_CURRENT_STATES)
    480 		si_dump_framebuffer(sctx, f);
    481 
    482 	if (flags & PIPE_DUMP_CURRENT_SHADERS) {
    483 		si_dump_shader(sctx->screen, &sctx->vs_shader, f);
    484 		si_dump_shader(sctx->screen, &sctx->tcs_shader, f);
    485 		si_dump_shader(sctx->screen, &sctx->tes_shader, f);
    486 		si_dump_shader(sctx->screen, &sctx->gs_shader, f);
    487 		si_dump_shader(sctx->screen, &sctx->ps_shader, f);
    488 
    489 		si_dump_descriptor_list(&sctx->descriptors[SI_DESCS_RW_BUFFERS],
    490 					"", "RW buffers", SI_NUM_RW_BUFFERS, f);
    491 		si_dump_descriptors(sctx, &sctx->vs_shader, f);
    492 		si_dump_descriptors(sctx, &sctx->tcs_shader, f);
    493 		si_dump_descriptors(sctx, &sctx->tes_shader, f);
    494 		si_dump_descriptors(sctx, &sctx->gs_shader, f);
    495 		si_dump_descriptors(sctx, &sctx->ps_shader, f);
    496 	}
    497 
    498 	if (flags & PIPE_DUMP_LAST_COMMAND_BUFFER) {
    499 		si_dump_bo_list(sctx, &sctx->last_gfx, f);
    500 		si_dump_last_ib(sctx, f);
    501 
    502 		fprintf(f, "Done.\n");
    503 
    504 		/* dump only once */
    505 		radeon_clear_saved_cs(&sctx->last_gfx);
    506 		r600_resource_reference(&sctx->last_trace_buf, NULL);
    507 	}
    508 }
    509 
    510 static void si_dump_dma(struct si_context *sctx,
    511 			struct radeon_saved_cs *saved, FILE *f)
    512 {
    513 	static const char ib_name[] = "sDMA IB";
    514 	unsigned i;
    515 
    516 	si_dump_bo_list(sctx, saved, f);
    517 
    518 	fprintf(f, "------------------ %s begin ------------------\n", ib_name);
    519 
    520 	for (i = 0; i < saved->num_dw; ++i) {
    521 		fprintf(f, " %08x\n", saved->ib[i]);
    522 	}
    523 
    524 	fprintf(f, "------------------- %s end -------------------\n", ib_name);
    525 	fprintf(f, "\n");
    526 
    527 	fprintf(f, "SDMA Dump Done.\n");
    528 }
    529 
    530 static bool si_vm_fault_occured(struct si_context *sctx, uint32_t *out_addr)
    531 {
    532 	char line[2000];
    533 	unsigned sec, usec;
    534 	int progress = 0;
    535 	uint64_t timestamp = 0;
    536 	bool fault = false;
    537 
    538 	FILE *p = popen("dmesg", "r");
    539 	if (!p)
    540 		return false;
    541 
    542 	while (fgets(line, sizeof(line), p)) {
    543 		char *msg, len;
    544 
    545 		if (!line[0] || line[0] == '\n')
    546 			continue;
    547 
    548 		/* Get the timestamp. */
    549 		if (sscanf(line, "[%u.%u]", &sec, &usec) != 2) {
    550 			static bool hit = false;
    551 			if (!hit) {
    552 				fprintf(stderr, "%s: failed to parse line '%s'\n",
    553 					__func__, line);
    554 				hit = true;
    555 			}
    556 			continue;
    557 		}
    558 		timestamp = sec * 1000000llu + usec;
    559 
    560 		/* If just updating the timestamp. */
    561 		if (!out_addr)
    562 			continue;
    563 
    564 		/* Process messages only if the timestamp is newer. */
    565 		if (timestamp <= sctx->dmesg_timestamp)
    566 			continue;
    567 
    568 		/* Only process the first VM fault. */
    569 		if (fault)
    570 			continue;
    571 
    572 		/* Remove trailing \n */
    573 		len = strlen(line);
    574 		if (len && line[len-1] == '\n')
    575 			line[len-1] = 0;
    576 
    577 		/* Get the message part. */
    578 		msg = strchr(line, ']');
    579 		if (!msg) {
    580 			assert(0);
    581 			continue;
    582 		}
    583 		msg++;
    584 
    585 		switch (progress) {
    586 		case 0:
    587 			if (strstr(msg, "GPU fault detected:"))
    588 				progress = 1;
    589 			break;
    590 		case 1:
    591 			msg = strstr(msg, "VM_CONTEXT1_PROTECTION_FAULT_ADDR");
    592 			if (msg) {
    593 				msg = strstr(msg, "0x");
    594 				if (msg) {
    595 					msg += 2;
    596 					if (sscanf(msg, "%X", out_addr) == 1)
    597 						fault = true;
    598 				}
    599 			}
    600 			progress = 0;
    601 			break;
    602 		default:
    603 			progress = 0;
    604 		}
    605 	}
    606 	pclose(p);
    607 
    608 	if (timestamp > sctx->dmesg_timestamp)
    609 		sctx->dmesg_timestamp = timestamp;
    610 	return fault;
    611 }
    612 
    613 void si_check_vm_faults(struct r600_common_context *ctx,
    614 			struct radeon_saved_cs *saved, enum ring_type ring)
    615 {
    616 	struct si_context *sctx = (struct si_context *)ctx;
    617 	struct pipe_screen *screen = sctx->b.b.screen;
    618 	FILE *f;
    619 	uint32_t addr;
    620 	char cmd_line[4096];
    621 
    622 	if (!si_vm_fault_occured(sctx, &addr))
    623 		return;
    624 
    625 	f = dd_get_debug_file(false);
    626 	if (!f)
    627 		return;
    628 
    629 	fprintf(f, "VM fault report.\n\n");
    630 	if (os_get_command_line(cmd_line, sizeof(cmd_line)))
    631 		fprintf(f, "Command: %s\n", cmd_line);
    632 	fprintf(f, "Driver vendor: %s\n", screen->get_vendor(screen));
    633 	fprintf(f, "Device vendor: %s\n", screen->get_device_vendor(screen));
    634 	fprintf(f, "Device name: %s\n\n", screen->get_name(screen));
    635 	fprintf(f, "Failing VM page: 0x%08x\n\n", addr);
    636 
    637 	if (sctx->apitrace_call_number)
    638 		fprintf(f, "Last apitrace call: %u\n\n",
    639 			sctx->apitrace_call_number);
    640 
    641 	switch (ring) {
    642 	case RING_GFX:
    643 		si_dump_debug_state(&sctx->b.b, f,
    644 				    PIPE_DUMP_CURRENT_STATES |
    645 				    PIPE_DUMP_CURRENT_SHADERS |
    646 				    PIPE_DUMP_LAST_COMMAND_BUFFER);
    647 		break;
    648 
    649 	case RING_DMA:
    650 		si_dump_dma(sctx, saved, f);
    651 		break;
    652 
    653 	default:
    654 		break;
    655 	}
    656 
    657 	fclose(f);
    658 
    659 	fprintf(stderr, "Detected a VM fault, exiting...\n");
    660 	exit(0);
    661 }
    662 
    663 void si_init_debug_functions(struct si_context *sctx)
    664 {
    665 	sctx->b.b.dump_debug_state = si_dump_debug_state;
    666 	sctx->b.check_vm_faults = si_check_vm_faults;
    667 
    668 	/* Set the initial dmesg timestamp for this context, so that
    669 	 * only new messages will be checked for VM faults.
    670 	 */
    671 	if (sctx->screen->b.debug_flags & DBG_CHECK_VM)
    672 		si_vm_fault_occured(sctx, NULL);
    673 }
    674