xref: /gfx-drm/usr/src/cmd/mdb/i915/i915.c (revision e1cb3391)
1 /*
2  * Copyright (c) 2012, 2013, Intel Corporation.
3  * All Rights Reserved.
4  */
5 /*
6  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the next
16  * paragraph) shall be included in all copies or substantial portions of the
17  * Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  */
27 
28 #include <sys/mdb_modapi.h>
29 #include <sys/proc.h>
30 
31 #include <drm/drmP.h>
32 #include <drm/i915_drm.h>
33 #include "i915_drv.h"
34 #include "intel_drv.h"
35 
36 
37 /*
38  * Defines
39  */
40 /* dcmd options */
41 #define	ACTIVE_LIST	0x01
42 #define	INACTIVE_LIST	0x02
43 #define	BOUND_LIST	0x04
44 #define	UNBOUND_LIST	0x08
45 
46 #define	RENDER_RING	0x01
47 #define	BLT_RING	0x02
48 #define	BSD_RING	0x04
49 
50 u32 count, mappable_count, purgeable_count;
51 size_t size, mappable_size, purgeable_size;
52 
53 /*
54  * Initialize the proc_t walker by either using the given starting address,
55  * or reading the value of the kernel's practive pointer.  We also allocate
56  * a proc_t for storage, and save this using the walk_data pointer.
57  */
58 static int
head_list_walk_init(mdb_walk_state_t * wsp)59 head_list_walk_init(mdb_walk_state_t *wsp)
60 {
61 
62 	if (wsp->walk_addr == NULL) {
63 		mdb_warn("head is NULL");
64 		return (WALK_ERR);
65 	}
66 
67 	wsp->walk_data = mdb_alloc(sizeof (struct list_head), UM_SLEEP);
68 
69 	if (mdb_vread(wsp->walk_data, sizeof (struct list_head),
70 	    wsp->walk_addr) == -1) {
71 		mdb_warn("failed to read list head at %p", wsp->walk_addr);
72 		return (WALK_DONE);
73 	}
74 
75 	wsp->walk_arg = (void *)wsp->walk_addr;
76 
77 	wsp->walk_addr =
78 	    (uintptr_t)(((struct list_head *)wsp->walk_data)->next);
79 
80 	return (WALK_NEXT);
81 }
82 
83 /*
84  * At each step, read a proc_t into our private storage, and then invoke
85  * the callback function.  We terminate when we reach a NULL p_next pointer.
86  */
87 static int
head_list_walk_step(mdb_walk_state_t * wsp)88 head_list_walk_step(mdb_walk_state_t *wsp)
89 {
90 	int status;
91 
92 	if (wsp->walk_addr == NULL) {
93 		mdb_warn("uncompletement list");
94 		return (WALK_DONE);
95 	}
96 
97 	if (mdb_vread(wsp->walk_data, sizeof (struct list_head),
98 	    wsp->walk_addr) == -1) {
99 		mdb_warn("failed to read list at %p", wsp->walk_addr);
100 		return (WALK_DONE);
101 	}
102 
103 	if ((void *)wsp->walk_addr == wsp->walk_arg) {
104 		return (WALK_DONE);
105 	}
106 
107 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
108 	    wsp->walk_cbdata);
109 
110 	wsp->walk_addr =
111 	    (uintptr_t)(((struct list_head *)wsp->walk_data)->next);
112 	return (status);
113 }
114 
115 /*
116  * The walker's fini function is invoked at the end of each walk.  Since we
117  * dynamically allocated a proc_t in sp_walk_init, we must free it now.
118  */
119 static void
head_list_walk_fini(mdb_walk_state_t * wsp)120 head_list_walk_fini(mdb_walk_state_t *wsp)
121 {
122 	mdb_free(wsp->walk_data, sizeof (proc_t));
123 }
124 
125 static int
get_drm_dev(struct drm_device * drm_dev)126 get_drm_dev(struct drm_device *drm_dev)
127 {
128 	uintptr_t i915_ss;
129 	void *state;
130 	i_ddi_soft_state *ss;
131 	uintptr_t array;
132 
133 	state = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
134 
135 	if (mdb_readsym(&i915_ss, sizeof (i915_ss),
136 	    "i915_statep") == -1) {
137 		mdb_warn("failed to read i915_statep");
138 		mdb_free(state, sizeof (struct drm_device));
139 		return (-1);
140 	}
141 
142 	if (mdb_vread(state, sizeof (struct drm_device), i915_ss) == -1) {
143 		mdb_warn("Failed to read state\n");
144 		mdb_free(state, sizeof (struct drm_device));
145 		return (-1);
146 	}
147 
148 	ss = (i_ddi_soft_state *) state;
149 
150 	if (mdb_vread(&array, sizeof (uintptr_t), (uintptr_t)ss->array) == -1) {
151 		mdb_warn("Failed to read array\n");
152 		mdb_free(state, sizeof (struct drm_device));
153 		return (-1);
154 	}
155 
156 	if (mdb_vread(drm_dev, sizeof (struct drm_device), array) == -1) {
157 		mdb_warn("Failed to read drm_dev\n");
158 		mdb_free(state, sizeof (struct drm_device));
159 		return (-1);
160 	}
161 	mdb_free(state, sizeof (struct drm_device));
162 
163 	return (DCMD_OK);
164 }
165 
166 static int
get_i915_private(struct drm_i915_private * dev_priv)167 get_i915_private(struct drm_i915_private *dev_priv)
168 {
169 	struct drm_device *drm_dev;
170 	int ret;
171 
172 	drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
173 	ret = get_drm_dev(drm_dev);
174 
175 	if (ret == DCMD_OK) {
176 		if (mdb_vread(dev_priv, sizeof (struct drm_i915_private),
177 		    (uintptr_t)drm_dev->dev_private) == -1) {
178 			mdb_warn("Failed to read i915 private\n");
179 			mdb_free(drm_dev, sizeof (struct drm_device));
180 			return (-1);
181 		}
182 	}
183 	mdb_free(drm_dev, sizeof (struct drm_device));
184 	return (ret);
185 }
186 
187 void
i915_pciid_help(void)188 i915_pciid_help(void)
189 {
190 	mdb_printf("Print device ID information of Intel graphics card.\n");
191 }
192 
193 /* ARGSUSED */
194 static int
i915_pciid(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)195 i915_pciid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
196 {
197 	int ret;
198 	struct drm_device *drm_dev;
199 
200 	if (flags & DCMD_ADDRSPEC) {
201 		mdb_printf("don't need to set address 0x%lx\n", addr);
202 		return (DCMD_OK);
203 	}
204 
205 	drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
206 
207 	ret = get_drm_dev(drm_dev);
208 	if (ret == DCMD_OK)
209 		mdb_printf(" vendor 0x%x device 0x%x\n",
210 		    drm_dev->pci_vendor, drm_dev->pci_device);
211 
212 	mdb_free(drm_dev, sizeof (struct drm_device));
213 	return (ret);
214 }
215 
216 void
i915_gtt_total_help(void)217 i915_gtt_total_help(void)
218 {
219 	mdb_printf("Print graphics translation table (GTT) size\n");
220 }
221 
222 /* ARGSUSED */
223 static int
i915_gtt_total(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)224 i915_gtt_total(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
225 {
226 	int ret;
227 	struct drm_i915_private *dev_priv;
228 
229 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
230 
231 	ret = get_i915_private(dev_priv);
232 	if (ret == DCMD_OK) {
233 		mdb_printf("gtt total size 0x%x", dev_priv->gtt.total);
234 		mdb_printf("gtt mappable size 0x%x",
235 		    dev_priv->gtt.mappable_end);
236 		mdb_printf("gtt stolen size 0x%x", dev_priv->gtt.stolen_size);
237 	}
238 
239 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
240 	return (ret);
241 }
242 
get_pin_flag(struct drm_i915_gem_object * obj)243 static const char *get_pin_flag(struct drm_i915_gem_object *obj)
244 {
245 	if (obj->user_pin_count > 0)
246 		return ("P");
247 	else if (obj->pin_count > 0)
248 		return ("p");
249 	else
250 		return (" ");
251 }
252 
get_tiling_flag(struct drm_i915_gem_object * obj)253 static const char *get_tiling_flag(struct drm_i915_gem_object *obj)
254 {
255 	switch (obj->tiling_mode) {
256 	default:
257 	case I915_TILING_NONE: return " ";
258 	case I915_TILING_X: return "X";
259 	case I915_TILING_Y: return "Y";
260 	}
261 }
262 
cache_level_str(int type)263 static const char *cache_level_str(int type)
264 {
265 	switch (type) {
266 	case I915_CACHE_NONE: return " uncached";
267 	case I915_CACHE_LLC: return " snooped (LLC)";
268 	case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)";
269 	default: return "";
270 	}
271 }
272 
273 static void
describe_obj(struct drm_i915_gem_object * obj)274 describe_obj(struct drm_i915_gem_object *obj)
275 {
276 
277 	mdb_printf("%p: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s",
278 	    &obj->base,
279 	    get_pin_flag(obj),
280 	    get_tiling_flag(obj),
281 	    obj->base.size / 1024,
282 	    obj->base.read_domains,
283 	    obj->base.write_domain,
284 	    obj->last_read_seqno,
285 	    obj->last_write_seqno,
286 	    obj->last_fenced_seqno,
287 	    cache_level_str(obj->cache_level),
288 	    obj->dirty ? " dirty" : "",
289 	    obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
290 	if (obj->base.name)
291 		mdb_printf(" (name: %d)", obj->base.name);
292 	if (obj->pin_count)
293 		mdb_printf(" (pinned x %d)", obj->pin_count);
294 	if (obj->fence_reg != I915_FENCE_REG_NONE)
295 		mdb_printf(" (fence: %d)", obj->fence_reg);
296 	if (obj->gtt_space != NULL)
297 		mdb_printf(" (gtt offset: %08x, size: %08x)",
298 		    obj->gtt_offset, (unsigned int)obj->base.real_size);
299 	if (obj->pin_mappable || obj->fault_mappable) {
300 		char s[3], *t = s;
301 		if (obj->pin_mappable)
302 			*t++ = 'p';
303 		if (obj->fault_mappable)
304 			*t++ = 'f';
305 		*t = '\0';
306 		mdb_printf(" (%s mappable)", s);
307 	}
308 
309 }
310 
311 static void
i915_obj_info(struct drm_i915_gem_object * obj)312 i915_obj_info(struct drm_i915_gem_object *obj)
313 {
314 
315 	/* "size", "gtt_off", "kaddr", "pfn_array" */
316 
317 	mdb_printf(" 0x%-8x  0x%-8x  0x%lx  0x%lx\n",
318 	    obj->base.real_size, obj->gtt_offset, obj->base.kaddr,
319 	    obj->base.pfnarray);
320 
321 	size += obj->base.real_size;
322 	++count;
323 	if (obj->map_and_fenceable) {
324 		mappable_size += obj->base.real_size;
325 		++mappable_count;
326 	}
327 
328 }
329 
330 void
i915_obj_list_node_help(void)331 i915_obj_list_node_help(void)
332 {
333 	mdb_printf("Print objects information for a given list pointer\n"
334 	"Fields printed:\n"
335 	"       obj:\tpointer to drm_i915_gem_object structure\n"
336 	"       size:\tobject size\n"
337 	"       gtt_off:\tobject offset in GTT (graphics address)\n"
338 	"       kaddr:\tobject kernel virtual address\n"
339 	"       pfn_array:\tArrary which contains object's PFN\n");
340 }
341 
342 /* ARGSUSED */
343 static int
i915_obj_list_node(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)344 i915_obj_list_node(uintptr_t addr, uint_t flags, int argc,
345     const mdb_arg_t *argv)
346 {
347 	int ret = DCMD_OK;
348 	struct list_head list;
349 	struct drm_i915_gem_object *obj;
350 
351 	if (!(flags & DCMD_ADDRSPEC))
352 		return (DCMD_USAGE);
353 
354 	if (mdb_vread(&list, sizeof (struct list), addr) == -1) {
355 		mdb_warn("failed to read list");
356 		return (DCMD_ERR);
357 	}
358 
359 	if (list.contain_ptr == 0) {
360 		mdb_warn("no object!");
361 		return (DCMD_ERR);
362 	}
363 
364 	obj = mdb_alloc(sizeof (struct drm_i915_gem_object), UM_SLEEP);
365 	if (mdb_vread(obj, sizeof (struct drm_i915_gem_object),
366 	    (uintptr_t)list.contain_ptr) == -1) {
367 		mdb_warn("failed to read object infor");
368 		ret = DCMD_ERR;
369 		goto err;
370 	}
371 
372 	mdb_printf("0x%lx ", list.contain_ptr);
373 	i915_obj_info(obj);
374 
375 err:
376 	mdb_free(obj, sizeof (struct drm_i915_gem_object));
377 	return (ret);
378 }
379 
380 static int
obj_walk_list(uintptr_t addr,const char * str)381 obj_walk_list(uintptr_t addr, const char *str)
382 {
383 	struct list_head *head;
384 	int ret = DCMD_OK;
385 
386 	head = mdb_alloc(sizeof (struct list_head), UM_SLEEP);
387 
388 	if (mdb_vread(head, sizeof (struct list_head), addr) == -1) {
389 		mdb_warn("failed to read active_list");
390 		ret = DCMD_ERR;
391 		goto err;
392 	}
393 	mdb_printf("Dump %s List\n", str);
394 	mdb_printf("%s %20s %14s %9s %23s\n", "obj", "size", "gtt_off",
395 	    "kaddr", "pfn_array");
396 
397 	if (mdb_pwalk_dcmd("head_list", "i915_obj_list_node",
398 	    0, NULL, (uintptr_t)head->prev) == -1) {
399 		mdb_warn("failed to walk head_list");
400 		ret = DCMD_ERR;
401 		goto err;
402 	}
403 err:
404 	mdb_free(head, sizeof (struct list_head));
405 	return (ret);
406 }
407 
408 void
i915_obj_list_help(void)409 i915_obj_list_help(void)
410 {
411 	mdb_printf("Print object lists information\n"
412 	    "Fields printed:\n"
413 	    "       obj:\tpointer to drm_i915_gem_object structure\n"
414 	    "       size:\tobject size\n"
415 	    "       gtt_off:\tobject offset in GTT (graphics address)\n"
416 	    "       kaddr:\tobject kernel virtual address\n"
417 	    "       pfn_array:\tArrary which contains object's PFN\n"
418 	    "Options:\n"
419 	    "       -a flag:\tprint only active list with flag set\n"
420 	    "       -i flag:\tprint only inactive list with flag set\n"
421 	    "       -b flag:\tprint only bound list with flag set\n"
422 	    "       -u flag:\tprint only unbound list with flag set\n"
423 	    "\nWithout the option, print information about all objects in "
424 	    "system.\n"
425 	    "Please make sure mdb_track is enabled in i915 driver by "
426 	    "mdb_track_enable,\n"
427 	    "before dump all objects information.\n");
428 }
429 
430 /* ARGSUSED */
431 static int
i915_obj_list(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)432 i915_obj_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
433 {
434 	uint_t	list_flag = 0;
435 	struct drm_i915_private *dev_priv;
436 	int ret = DCMD_OK;
437 
438 	if (flags & DCMD_ADDRSPEC) {
439 		mdb_printf("don't need to set address 0x%lx, just ignore\n",
440 		    addr);
441 	}
442 
443 	if (mdb_getopts(argc, argv,
444 	    'a', MDB_OPT_SETBITS, ACTIVE_LIST, &list_flag,
445 	    'i', MDB_OPT_SETBITS, INACTIVE_LIST, &list_flag,
446 	    'b', MDB_OPT_SETBITS, BOUND_LIST, &list_flag,
447 	    'u', MDB_OPT_SETBITS, UNBOUND_LIST, &list_flag, NULL) != argc) {
448 		mdb_printf("\nUsage:\n"
449 		    "-a dump active_list\n"
450 		    "-i dump inactive_list\n"
451 		    "-b dump bound_list\n"
452 		    "-u dump unbound_list\n");
453 		return (DCMD_USAGE);
454 	}
455 
456 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
457 	ret = get_i915_private(dev_priv);
458 	if (ret != DCMD_OK) {
459 		goto err;
460 	}
461 
462 	mdb_printf("%u objects, 0x%lx bytes\n",
463 	    dev_priv->mm.object_count, dev_priv->mm.object_memory);
464 
465 	if (list_flag == 0) {
466 		int mdb_track = 0;
467 		if (mdb_readvar(&mdb_track, "mdb_track_enable") == -1) {
468 			mdb_warn("failed to read mdb_track");
469 			mdb_track = 0;
470 		}
471 
472 		if (mdb_track == 0) {
473 			mdb_printf("mdb_track is not enabled. Please enable "
474 			    "it by set drm:mdb_track_enable=1");
475 			goto err;
476 		}
477 
478 		/* dump whole gem objects list */
479 		struct drm_device *drm_dev;
480 		struct list_head *head;
481 		drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
482 		ret = get_drm_dev(drm_dev);
483 		if (ret != DCMD_OK)
484 			goto err2;
485 
486 		head = mdb_alloc(sizeof (struct list_head), UM_SLEEP);
487 		if (mdb_vread(head, sizeof (struct list_head),
488 		    (uintptr_t)drm_dev->gem_objects_list.next) == -1) {
489 			mdb_warn("failed to read whole gem list");
490 			ret = DCMD_ERR;
491 			goto err1;
492 		}
493 
494 		mdb_printf("Dump %s List\n", "Whole gem objects");
495 		mdb_printf("%s %20s %14s %9s %23s\n", "obj", "size",
496 		    "gtt_off", "kaddr", "pfn_array");
497 
498 		if (mdb_pwalk_dcmd("head_list", "i915_obj_list_node",
499 		    0, NULL, (uintptr_t)head->prev) == -1) {
500 			mdb_warn("failed to walk head_list");
501 			ret = DCMD_ERR;
502 			goto err;
503 		}
504 err1:
505 		mdb_free(head, sizeof (struct list_head));
506 err2:
507 		mdb_free(drm_dev, sizeof (struct drm_device));
508 		goto err;
509 	}
510 	if (list_flag & ACTIVE_LIST) {
511 		size = count = mappable_size = mappable_count = 0;
512 		ret = obj_walk_list((uintptr_t)dev_priv->mm.active_list.next,
513 		    "Activate");
514 		if (ret != DCMD_OK)
515 			goto err;
516 		mdb_printf("  %u [%u] active objects, 0x%lx [0x%lx] bytes\n",
517 		    count, mappable_count, size, mappable_size);
518 
519 	}
520 
521 	if (list_flag & INACTIVE_LIST) {
522 		size = count = mappable_size = mappable_count = 0;
523 		ret = obj_walk_list((uintptr_t)dev_priv->mm.inactive_list.next,
524 		    "Inactivate");
525 		if (ret != DCMD_OK)
526 			goto err;
527 		mdb_printf("  %u [%u] inactive objects, 0x%lx [0x%lx] bytes\n",
528 		    count, mappable_count, size, mappable_size);
529 	}
530 
531 	if (list_flag & BOUND_LIST) {
532 		size = count = mappable_size = mappable_count = 0;
533 		ret = obj_walk_list((uintptr_t)dev_priv->mm.bound_list.next,
534 		    "Bound");
535 		if (ret != DCMD_OK)
536 			goto err;
537 		mdb_printf("%u [%u] objects, 0x%lx [0x%lx] bytes in gtt\n",
538 		    count, mappable_count, size, mappable_size);
539 
540 	}
541 
542 	if (list_flag & UNBOUND_LIST) {
543 		size = count = purgeable_size = purgeable_count = 0;
544 		ret = obj_walk_list((uintptr_t)dev_priv->mm.unbound_list.next,
545 		    "Unbound");
546 		if (ret != DCMD_OK)
547 			goto err;
548 		mdb_printf("%u unbound objects, 0x%lx bytes\n", count, size);
549 	}
550 
551 err:
552 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
553 	return (ret);
554 }
555 
556 void
i915_ringbuffer_info_help(void)557 i915_ringbuffer_info_help(void)
558 {
559 	mdb_printf("Print ring object information\n"
560 	"Fields printed:\n"
561 	"       mmio_base:\tMMIO base address\n"
562 	"       obj:\tpointer to ring object's drm_i915_gem_object structure\n"
563 	"Options:\n"
564 	"       -l flag:\tprint only BLT ring information with flag set\n"
565 	"       -r flag:\tprint only RENDER ring information with flag set\n"
566 	"       -s flag:\tprint only BSD ring information with flag set\n"
567 	"Without the option given, print information about all rings.\n");
568 }
569 
570 /* ARGSUSED */
571 static int
i915_ringbuffer_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)572 i915_ringbuffer_info(uintptr_t addr, uint_t flags, int argc,
573     const mdb_arg_t *argv)
574 {
575 	struct drm_i915_private *dev_priv;
576 	uint_t  ring_flag = 0;
577 	int ret = DCMD_OK;
578 
579 	if (flags & DCMD_ADDRSPEC) {
580 		mdb_printf("don't need to set address 0x%lx, just ignore\n",
581 		    addr);
582 	}
583 
584 	if (mdb_getopts(argc, argv,
585 	    'l', MDB_OPT_SETBITS, BLT_RING, &ring_flag,
586 	    'r', MDB_OPT_SETBITS, RENDER_RING, &ring_flag,
587 	    's', MDB_OPT_SETBITS, BSD_RING, &ring_flag, NULL) != argc) {
588 		mdb_printf("\nUsage:\n"
589 		    "-l blt ring information\n"
590 		    "-r render ring information\n"
591 		    "-s bsd ring information\n");
592 		return (DCMD_USAGE);
593 	}
594 
595 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
596 	ret = get_i915_private(dev_priv);
597 		if (ret != DCMD_OK) {
598 		goto err;
599 	}
600 
601 	if (ring_flag == 0)
602 		ring_flag = 0xff;
603 
604 	if (ring_flag & RENDER_RING) {
605 		mdb_printf("Render ring mmio_base 0x%lx obj 0x%lx\n",
606 		    dev_priv->ring[0].mmio_base,
607 		    dev_priv->ring[0].obj);
608 	}
609 
610 	if (ring_flag & BLT_RING) {
611 		mdb_printf("BLT ring mmio_base 0x%lx obj 0x%lx\n",
612 		    dev_priv->ring[2].mmio_base,
613 		    dev_priv->ring[2].obj);
614 	}
615 
616 	if (ring_flag & BSD_RING) {
617 		mdb_printf("BSD ring mmio_base 0x%lx obj 0x%lx\n",
618 		    dev_priv->ring[1].mmio_base,
619 		    dev_priv->ring[1].obj);
620 	}
621 
622 err:
623 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
624 	return (ret);
625 }
626 
627 void
i915_gtt_dump_help(void)628 i915_gtt_dump_help(void)
629 {
630 	mdb_printf("Print the address of gtt_dump\n"
631 	    "\ngtt_dump is a snapshot of whole GTT table when GPU hang "
632 	    "happened.\n"
633 	    "Please make sure gpu_dump is enabled in i915 driver before "
634 	    "using it.\n"
635 	    "\nSee also: \"::help i915_error_reg_dump\"\n");
636 }
637 
638 /* ARGSUSED */
639 static int
i915_gtt_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)640 i915_gtt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
641 {
642 	struct drm_device *drm_dev;
643 	int ret = DCMD_OK;
644 
645 	drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
646 	ret = get_drm_dev(drm_dev);
647 	if (ret != DCMD_OK) {
648 		goto err;
649 	}
650 
651 	if (drm_dev->gtt_dump != 0)
652 		mdb_printf("gtt_dump address 0x%lx\n", drm_dev->gtt_dump);
653 	else
654 		mdb_printf("There is no gtt_dump");
655 
656 err:
657 	mdb_free(drm_dev, sizeof (struct drm_device));
658 	return (ret);
659 }
660 
661 static uint32_t
i915_read(struct drm_i915_private * dev_priv,uintptr_t addr,uint32_t * val)662 i915_read(struct drm_i915_private *dev_priv, uintptr_t addr, uint32_t *val)
663 {
664 	struct drm_local_map regs;
665 	int ret = DCMD_OK;
666 
667 	if (mdb_vread(&regs, sizeof (struct drm_local_map),
668 	    (intptr_t)dev_priv->regs) == -1) {
669 		mdb_warn("Failed to read dev_priv->regs\n");
670 		ret = DCMD_ERR;
671 		return (ret);
672 	}
673 
674 	if (mdb_pread(val, sizeof (uint32_t),
675 	    (intptr_t)regs.offset + addr) == -1) {
676 		mdb_warn("Failed to read register 0x%x\n", addr);
677 		ret = DCMD_ERR;
678 		return (ret);
679 	}
680 
681 	return (ret);
682 
683 }
684 
685 void
i915_register_read_help(void)686 i915_register_read_help(void)
687 {
688 	mdb_printf("Print register value for a given register offset\n");
689 }
690 
691 /* ARGSUSED */
692 static int
i915_register_read(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)693 i915_register_read(uintptr_t addr, uint_t flags, int argc,
694     const mdb_arg_t *argv)
695 {
696 	struct drm_i915_private *dev_priv;
697 	int ret = DCMD_OK;
698 	uint32_t val;
699 
700 	if (!(flags & DCMD_ADDRSPEC)) {
701 		return (DCMD_USAGE);
702 	}
703 
704 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
705 	ret = get_i915_private(dev_priv);
706 	if (ret != DCMD_OK) {
707 		goto err;
708 	}
709 	ret = i915_read(dev_priv, addr, &val);
710 	if (ret == DCMD_ERR) {
711 		goto err;
712 	}
713 
714 	mdb_printf("Register [0x%x]: 0x%x\n", addr, val);
715 err:
716 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
717 	return (ret);
718 }
719 
720 void
i915_error_reg_dump_help(void)721 i915_error_reg_dump_help(void)
722 {
723 	mdb_printf("Print debug register information\n"
724 	"Registers printed:\n"
725 	"       PGTBL_ER:\tPage Table Errors Register\n"
726 	"       INSTPM:\tCommand Parser Mode Register\n"
727 	"       EIR:\tError Identity Register\n"
728 	"       EHR:\tError Header Register\n"
729 	"       INSTDONE:\tInstruction Stream Interface Done Register\n"
730 	"       INSTDONE1:\tInstruction Stream Interface Done 1\n"
731 	"       INSTPS:\tInstruction Parser State Register\n"
732 	"       ACTHD:\tActive Head Pointer Register\n"
733 	"       DMA_FADD_P:\tPrimary DMA Engine Fetch Address Register\n"
734 	"\ngtt_dump is a snapshot of whole GTT table when GPU hang happened.\n"
735 	"\nSee also: \"::help i915_gtt_dump\"\n");
736 }
737 
738 /* ARGSUSED */
739 static int
i915_error_reg_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)740 i915_error_reg_dump(uintptr_t addr, uint_t flags, int argc,
741     const mdb_arg_t *argv)
742 {
743 	struct drm_device *dev;
744 	struct drm_i915_private *dev_priv;
745 	int ret = DCMD_OK;
746 	uint32_t val;
747 
748 	if (flags & DCMD_ADDRSPEC) {
749 		mdb_printf("don't need to set address 0x%lx\n", addr);
750 		return (DCMD_OK);
751 	}
752 
753 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
754 	ret = get_drm_dev(dev);
755 	if (ret == DCMD_ERR)
756 		goto err1;
757 
758 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
759 	ret = get_i915_private(dev_priv);
760 	if (ret != DCMD_OK) {
761 		goto err2;
762 	}
763 
764 	ret = i915_read(dev_priv, (uintptr_t)PGTBL_ER, &val);
765 	if (ret == DCMD_OK)
766 		mdb_printf("PGTBL_ER: 0x%lx\n", val);
767 
768 	ret = i915_read(dev_priv, (uintptr_t)INSTPM, &val);
769 	if (ret == DCMD_OK)
770 		mdb_printf("INSTPM: 0x%lx\n", val);
771 
772 	ret = i915_read(dev_priv, (uintptr_t)EIR, &val);
773 	if (ret == DCMD_OK)
774 		mdb_printf("EIR: 0x%lx\n", val);
775 
776 	ret = i915_read(dev_priv, (uintptr_t)ERROR_GEN6, &val);
777 	if (ret == DCMD_OK)
778 		mdb_printf("ERROR_GEN6: 0x%lx\n", val);
779 
780 	mdb_printf("\nBlitter command stream:\n");
781 	ret = i915_read(dev_priv, (uintptr_t)0x22064, &val);
782 	if (ret == DCMD_OK)
783 		mdb_printf("  BLT EIR: 0x%08x\n", val);
784 
785 	ret = i915_read(dev_priv, (uintptr_t)0x22068, &val);
786 	if (ret == DCMD_OK)
787 		mdb_printf("  BLT EHR: 0x%08x\n", val);
788 
789 	ret = i915_read(dev_priv, (uintptr_t)0x2206C, &val);
790 	if (ret == DCMD_OK)
791 		mdb_printf("  INSTDONE: 0x%08x\n", val);
792 
793 	ret = i915_read(dev_priv, (uintptr_t)0x22074, &val);
794 	if (ret == DCMD_OK)
795 		mdb_printf("  ACTHD: 0x%08x\n", val);
796 
797 
798 	mdb_printf("\nRender command stream:\n");
799 	ret = i915_read(dev_priv, (uintptr_t)IPEIR_I965, &val);
800 	if (ret == DCMD_OK)
801 		mdb_printf("  RENDER EIR: 0x%08x\n", val);
802 
803 	ret = i915_read(dev_priv, (uintptr_t)IPEHR_I965, &val);
804 	if (ret == DCMD_OK)
805 		mdb_printf("  RENDER EHR: 0x%08x\n", val);
806 
807 	ret = i915_read(dev_priv, (uintptr_t)INSTDONE_I965, &val);
808 	if (ret == DCMD_OK)
809 		mdb_printf("  INSTDONE: 0x%08x\n", val);
810 
811 	ret = i915_read(dev_priv, (uintptr_t)INSTPS, &val);
812 	if (ret == DCMD_OK)
813 		mdb_printf("  INSTPS: 0x%08x\n", val);
814 
815 	ret = i915_read(dev_priv, (uintptr_t)INSTDONE1, &val);
816 	if (ret == DCMD_OK)
817 		mdb_printf("  INSTDONE1: 0x%08x\n", val);
818 
819 	ret = i915_read(dev_priv, (uintptr_t)ACTHD_I965, &val);
820 	if (ret == DCMD_OK)
821 		mdb_printf("  ACTHD: 0x%08x\n", val);
822 
823 	ret = i915_read(dev_priv, (uintptr_t)0x2078, &val);
824 	if (ret == DCMD_OK)
825 		mdb_printf("  DMA_FADD_P: 0x%08x\n", val);
826 
827 	ret = i915_read(dev_priv, (uintptr_t)0x04094, &val);
828 	if (ret == DCMD_OK)
829 		mdb_printf("\nGraphics Engine Fault 0x%lx\n", val);
830 
831 	ret = i915_read(dev_priv, (uintptr_t)0x04194, &val);
832 	if (ret == DCMD_OK)
833 		mdb_printf("Media Engine Fault 0x%lx\n", val);
834 
835 	ret = i915_read(dev_priv, (uintptr_t)0x04294, &val);
836 	if (ret == DCMD_OK)
837 		mdb_printf("Blitter  Engine Fault 0x%lx\n", val);
838 
839 	if (dev->gtt_dump != NULL)
840 		mdb_printf("gtt dump to %p\n", dev->gtt_dump);
841 	else
842 		mdb_printf("no gtt dump\n");
843 err2:
844 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
845 err1:
846 	mdb_free(dev, sizeof (struct drm_device));
847 
848 	return (ret);
849 
850 }
851 
852 void
i915_obj_history_help(void)853 i915_obj_history_help(void)
854 {
855 	mdb_printf("Print object history information for a given "
856 	    "drm_i915_gem_object pointer\n"
857 	    "Fields printed:\n"
858 	    "       event:\tOperation name\n"
859 	    "       cur_seq:\tCurrent system SeqNO\n"
860 	    "       last_seq:\tLast SeqNO has been processed\n"
861 	    "       ring addr:\tPoint to intel_ring_buffer structure\n"
862 	    "\nNOTE: Please make sure mdb_track is enabled in i915 driver "
863 	    "by setting mdb_track_enable\n");
864 }
865 
866 /* ARGSUSED */
867 static int
i915_obj_history(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)868 i915_obj_history(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
869 {
870 	struct drm_gem_object obj;
871 	struct list_head node;
872 	uintptr_t temp;
873 	struct drm_history_list history_node;
874 	int ret = DCMD_OK;
875 	int condition = 1;
876 	int mdb_track = 0;
877 
878 	if (!(flags & DCMD_ADDRSPEC)) {
879 		return (DCMD_USAGE);
880 	}
881 
882 	if (mdb_vread(&obj, sizeof (struct drm_gem_object), addr) == -1) {
883 		mdb_warn("failed to read gem object infor");
884 		ret = DCMD_ERR;
885 		goto err;
886 	}
887 
888 	if (mdb_readvar(&mdb_track, "mdb_track_enable") == -1) {
889 		mdb_warn("failed to read mdb_track");
890 		mdb_track = 0;
891 	}
892 
893 	if (mdb_track == 0) {
894 		mdb_printf("mdb_track is not enabled. Please enable it "
895 		    "by set drm:mdb_track_enable=1");
896 		goto err;
897 	}
898 
899 	mdb_printf("Dump obj history\n");
900 	mdb_printf("%s %20s %10s %10s\n", "event", "cur_seq", "last_seq",
901 	    "ring addr");
902 	temp = (uintptr_t)obj.his_list.next;
903 	while (condition) {
904 		if (mdb_vread(&node, sizeof (struct list_head), temp) == -1) {
905 			mdb_warn("failed to read his_list node");
906 			ret = DCMD_ERR;
907 			goto err;
908 		}
909 
910 		if (node.contain_ptr == NULL)
911 			break;
912 
913 		if (mdb_vread(&history_node, sizeof (struct drm_history_list),
914 		    (uintptr_t)node.contain_ptr) == -1) {
915 			mdb_warn("failed to read history node");
916 			ret = DCMD_ERR;
917 			goto err;
918 		}
919 
920 		mdb_printf("%s %-8d %-8d 0x%lx\n", history_node.info,
921 		    history_node.cur_seq, history_node.last_seq,
922 		    history_node.ring_ptr);
923 
924 		temp = (uintptr_t)node.next;
925 	}
926 
927 err:
928 	return (ret);
929 }
930 
931 void
i915_batch_history_help(void)932 i915_batch_history_help(void)
933 {
934 	mdb_printf("Print batchbuffer information\n"
935 	    "\nAll batchbuffers' information is printed one by one "
936 	    "from the latest one to the oldest one.\n"
937 	    "The information includes objects number, assigned SeqNO. "
938 	    "and objects list.\n"
939 	    "\nNOTE: Please make sure mdb_track is enabled in i915 "
940 	    "driver by setting mdb_track_enable\n");
941 
942 }
943 
944 /* ARGSUSED */
945 static int
i915_batch_history(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)946 i915_batch_history(uintptr_t addr, uint_t flags, int argc,
947     const mdb_arg_t *argv)
948 {
949 	struct list_head node;
950 	uintptr_t temp;
951 	struct batch_info_list batch_node;
952 	caddr_t *obj_list;
953 	int ret, i;
954 	struct drm_i915_private *dev_priv;
955 	int condition = 1;
956 	int mdb_track = 0;
957 
958 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
959 
960 	ret = get_i915_private(dev_priv);
961 	if (ret != DCMD_OK) {
962 		mdb_warn("failed to read history node");
963 		goto err;
964 	}
965 
966 	if (mdb_readvar(&mdb_track, "mdb_track_enable") == -1) {
967 		mdb_warn("failed to read mdb_track");
968 		mdb_track = 0;
969 	}
970 	if (mdb_track == 0) {
971 		mdb_printf("mdb_track is not enabled. Please enable it by "
972 		    "set drm:mdb_track_enable=1");
973 		goto err;
974 	}
975 
976 	mdb_printf("Dump batchbuffer history\n");
977 	temp = (uintptr_t)dev_priv->batch_list.next;
978 	while (condition) {
979 
980 		if (mdb_vread(&node, sizeof (struct list_head), temp) == -1) {
981 			mdb_warn("failed to read his_list node");
982 			ret = DCMD_ERR;
983 			goto err;
984 		}
985 
986 		if (node.contain_ptr == NULL)
987 			break;
988 
989 		if (mdb_vread(&batch_node, sizeof (struct batch_info_list),
990 		    (uintptr_t)node.contain_ptr) == -1) {
991 			mdb_warn("failed to read batch node");
992 			ret = DCMD_ERR;
993 			goto err;
994 		}
995 
996 		mdb_printf("batch buffer includes %d objects, seqno 0x%x\n",
997 		    batch_node.num, batch_node.seqno);
998 
999 		obj_list = mdb_alloc(batch_node.num * sizeof (caddr_t),
1000 		    UM_SLEEP);
1001 		if (mdb_vread(obj_list, batch_node.num * sizeof (caddr_t),
1002 		    (uintptr_t)batch_node.obj_list) == -1) {
1003 			mdb_warn("failed to read batch object list");
1004 			ret = DCMD_ERR;
1005 			goto err;
1006 		}
1007 
1008 
1009 		for (i = 0; i < batch_node.num; i++) {
1010 			mdb_printf("obj: 0x%lx\n", obj_list[i]);
1011 		}
1012 
1013 		mdb_free(obj_list, batch_node.num * sizeof (caddr_t));
1014 
1015 		temp = (uintptr_t)node.next;
1016 	}
1017 
1018 err:
1019 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1020 	return (ret);
1021 }
1022 
yesno(int v)1023 static const char *yesno(int v)
1024 {
1025 	return (v ? "yes" : "no");
1026 }
1027 
1028 void
i915_capabilities_help(void)1029 i915_capabilities_help(void)
1030 {
1031 	mdb_printf("Print capability information for Intel graphics card\n"
1032 	    "Fields printed:\n"
1033 	    "	is_mobile:\tMobile Platform\n"
1034 	    "       is_i85x:\tIntel I85x series graphics card\n"
1035 	    "       is_i915g:\tIntel I915g series graphics card\n"
1036 	    "       is_i945gm:\tIntel I945gm series graphics card\n"
1037 	    "       is_g33:\tIntel G33 series graphics card\n"
1038 	    "       need_gfx_hws:\tNeed setup graphics hardware status page\n"
1039 	    "       is_g4x:\tIntel G4x series graphics card\n"
1040 	    "       is_pineview:\tIntel Pineview series graphics card\n"
1041 	    "       is_broadwater:\tIntel Broadwater series graphics card\n"
1042 	    "       is_crestline:\tIntel Crestline series graphics card\n"
1043 	    "       is_ivybridge:\tIntel Ivybridge series graphics card\n"
1044 	    "       is_valleyview:\tIntel Valleyview series graphics card\n"
1045 	    "       has_force_wake:\tHas force awake\n"
1046 	    "       is_haswell:\tIntel Haswell series graphics card\n"
1047 	    "       has_fbc:\tHas Framebuffer compression\n"
1048 	    "       has_pipe_cxsr:\tHas CxSR\n"
1049 	    "       has_hotplug:\tHas output hotplug\n"
1050 	    "       cursor_needs_physical:\tHas physical cursor object\n"
1051 	    "       has_overlay:\tHas Overlay\n"
1052 	    "       overlay_needs_physical:\tHas physical overlay object\n"
1053 	    "       supports_tv:\tSupport TV output\n"
1054 	    "       has_bsd_ring:\tHas BSD ring\n"
1055 	    "       has_blt_ring:\tHas BLT ring\n"
1056 	    "       has_llc:\tHas last level cache\n");
1057 }
1058 
1059 /* ARGSUSED */
1060 static int
i915_capabilities(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1061 i915_capabilities(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1062 {
1063 	int ret;
1064 	struct drm_device *drm_dev;
1065 	struct drm_i915_private *dev_priv;
1066 	struct intel_device_info info;
1067 
1068 	if (flags & DCMD_ADDRSPEC) {
1069 		mdb_printf("don't need to set address 0x%lx\n", addr);
1070 		return (DCMD_OK);
1071 	}
1072 
1073 	drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
1074 
1075 	ret = get_drm_dev(drm_dev);
1076 	if (ret == DCMD_ERR)
1077 		goto err1;
1078 
1079 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1080 	ret = get_i915_private(dev_priv);
1081 	if (ret != DCMD_OK) {
1082 		goto err2;
1083 	}
1084 
1085 	if (mdb_vread(&info, sizeof (struct intel_device_info),
1086 	    (uintptr_t)dev_priv->info) == -1) {
1087 		mdb_warn("failed to read i915 chip info");
1088 		ret = DCMD_ERR;
1089 		goto err2;
1090 	}
1091 
1092 	mdb_printf("gen: %d\n", info.gen);
1093 	mdb_printf("pch: %d\n", dev_priv->pch_type);
1094 
1095 
1096 /* BEGIN CSTYLED */
1097 #define	SEP_SEMICOLON	;
1098 #define	DEFINE_FLAG(x)	mdb_printf(#x ": %s\n", yesno(info.x))
1099 	DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
1100 #undef	DEFINE_FLAG
1101 #undef	SEP_SEMICOLON
1102 /* END CSTYLED */
1103 
1104 err2:
1105 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1106 err1:
1107 	mdb_free(drm_dev, sizeof (struct drm_device));
1108 	return (ret);
1109 }
1110 
1111 void
i915_request_list_node_help(void)1112 i915_request_list_node_help(void)
1113 {
1114 	mdb_printf("Print request list information for a given list pointer\n"
1115 	    "The information includes request, SeqNO. and timestamp.\n");
1116 }
1117 
1118 /* ARGSUSED */
1119 static int
i915_request_list_node(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1120 i915_request_list_node(uintptr_t addr, uint_t flags, int argc,
1121     const mdb_arg_t *argv)
1122 {
1123 	int ret = DCMD_OK;
1124 	struct list_head list;
1125 	struct drm_i915_gem_request *request;
1126 
1127 	if (!(flags & DCMD_ADDRSPEC))
1128 		return (DCMD_USAGE);
1129 
1130 	if (mdb_vread(&list, sizeof (struct list), addr) == -1) {
1131 		mdb_warn("failed to read list");
1132 		return (DCMD_ERR);
1133 	}
1134 
1135 	if (list.contain_ptr == 0) {
1136 		mdb_warn("no request!");
1137 		return (DCMD_ERR);
1138 	}
1139 
1140 	request = mdb_alloc(sizeof (struct drm_i915_gem_request), UM_SLEEP);
1141 	if (mdb_vread(request, sizeof (struct drm_i915_gem_request),
1142 	    (uintptr_t)list.contain_ptr) == -1) {
1143 		mdb_warn("failed to read request infor");
1144 		ret = DCMD_ERR;
1145 		goto err;
1146 	}
1147 
1148 	mdb_printf("0x%lx ", list.contain_ptr);
1149 	mdb_printf("    %d @ %ld\n", request->seqno, request->emitted_jiffies);
1150 
1151 err:
1152 	mdb_free(request, sizeof (struct drm_i915_gem_request));
1153 	return (ret);
1154 }
1155 
1156 static int
request_walk_list(uintptr_t addr,const char * str)1157 request_walk_list(uintptr_t addr, const char *str)
1158 {
1159 	struct list_head *head;
1160 	int ret = DCMD_OK;
1161 
1162 	mdb_printf("Dump %s ring request List %p\n", str, addr);
1163 
1164 	head = mdb_alloc(sizeof (struct list_head), UM_SLEEP);
1165 	if (mdb_vread(head, sizeof (struct list_head), addr) == -1) {
1166 		mdb_warn("failed to render ring request list");
1167 		ret = DCMD_ERR;
1168 		goto err;
1169 	}
1170 
1171 	if (mdb_pwalk_dcmd("head_list", "i915_request_list_node",
1172 	    0, NULL, (uintptr_t)head->prev) == -1) {
1173 		mdb_warn("failed to walk request head_list");
1174 		ret = DCMD_ERR;
1175 		goto err;
1176 	}
1177 
1178 err:
1179 	mdb_free(head, sizeof (struct list_head));
1180 	return (ret);
1181 
1182 }
1183 
1184 void
i915_gem_request_info_help(void)1185 i915_gem_request_info_help(void)
1186 {
1187 	mdb_printf("Print request list for each ring buffer\n"
1188 	    "\nSee also: \"::help i915_request_list_node\"\n");
1189 }
1190 
1191 /* ARGSUSED */
1192 static int
i915_gem_request_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1193 i915_gem_request_info(uintptr_t addr, uint_t flags, int argc,
1194     const mdb_arg_t *argv)
1195 {
1196 	struct drm_i915_private *dev_priv;
1197 	int ret = DCMD_OK;
1198 
1199 	if (flags & DCMD_ADDRSPEC) {
1200 		mdb_printf("don't need to set address 0x%lx, just ignore\n",
1201 		    addr);
1202 	}
1203 
1204 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1205 	ret = get_i915_private(dev_priv);
1206 	if (ret != DCMD_OK) {
1207 		goto err;
1208 	}
1209 
1210 	ret = request_walk_list((uintptr_t)dev_priv->ring[0].request_list.next,
1211 	    "RENDER");
1212 	if (ret != DCMD_OK) {
1213 		goto err;
1214 	}
1215 	ret = request_walk_list((uintptr_t)dev_priv->ring[1].request_list.next,
1216 	    "BSD");
1217 	if (ret != DCMD_OK) {
1218 		goto err;
1219 	}
1220 	ret = request_walk_list((uintptr_t)dev_priv->ring[2].request_list.next,
1221 	    "BLT");
1222 	if (ret != DCMD_OK) {
1223 		goto err;
1224 	}
1225 
1226 err:
1227 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1228 	return (ret);
1229 }
1230 
1231 static int
get_hws_info(uintptr_t addr,const char * str,int index)1232 get_hws_info(uintptr_t addr, const char *str, int index)
1233 {
1234 	u32 *regs;
1235 	int i, ret = DCMD_OK;
1236 
1237 	regs = mdb_alloc(0x4000, UM_SLEEP);
1238 	if (mdb_vread(regs, 0x4000,
1239 	    addr) == -1) {
1240 		mdb_warn("failed to read hardware status page");
1241 		ret = DCMD_ERR;
1242 		goto err;
1243 	}
1244 
1245 	if (index < 0) {
1246 		for (i = 0; i < 4096 / sizeof (u32) / 4; i += 4) {
1247 			mdb_printf("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
1248 			    i * 4, regs[i], regs[i + 1], regs[i + 2],
1249 			    regs[i + 3]);
1250 		}
1251 	} else
1252 		mdb_printf("%s ring seqno %d \n", str, regs[index]);
1253 err:
1254 	mdb_free(regs, 0x4000);
1255 return (ret);
1256 
1257 }
1258 
1259 void
i915_ring_seqno_info_help(void)1260 i915_ring_seqno_info_help(void)
1261 {
1262 	mdb_printf("Print current SeqNO. for each ring buffer\n");
1263 }
1264 
1265 /* ARGSUSED */
1266 static int
i915_ring_seqno_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1267 i915_ring_seqno_info(uintptr_t addr, uint_t flags, int argc,
1268     const mdb_arg_t *argv)
1269 {
1270 	struct drm_i915_private *dev_priv;
1271 	int ret = DCMD_OK;
1272 
1273 	if (flags & DCMD_ADDRSPEC) {
1274 		mdb_printf("don't need to set address 0x%lx\n", addr);
1275 		return (DCMD_OK);
1276 	}
1277 
1278 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1279 	ret = get_i915_private(dev_priv);
1280 	if (ret != DCMD_OK) {
1281 		goto err;
1282 	}
1283 
1284 	ret = get_hws_info((uintptr_t)dev_priv->ring[0].status_page.page_addr,
1285 	    "RENDER", I915_GEM_HWS_INDEX);
1286 	if (ret != DCMD_OK) {
1287 		goto err;
1288 	}
1289 	ret = get_hws_info((uintptr_t)dev_priv->ring[1].status_page.page_addr,
1290 	    "BSD", I915_GEM_HWS_INDEX);
1291 	if (ret != DCMD_OK) {
1292 		goto err;
1293 	}
1294 	ret = get_hws_info((uintptr_t)dev_priv->ring[2].status_page.page_addr,
1295 	    "BLT", I915_GEM_HWS_INDEX);
1296 	if (ret != DCMD_OK) {
1297 		goto err;
1298 	}
1299 
1300 
1301 err:
1302 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1303 	return (ret);
1304 
1305 }
1306 
1307 void
i915_gem_fence_regs_info_help(void)1308 i915_gem_fence_regs_info_help(void)
1309 {
1310 	mdb_printf("Print current Fence registers information\n"
1311 	"The information includes object address, user pin flag, tiling mode,\n"
1312 	"size, read domain, write domain, read SeqNO, write SeqNO, fence "
1313 	"SeqNo,\n"
1314 	"catch level, dirty info, object name, pin count, fence reg number,\n"
1315 	"GTT offset, pin mappable and fault mappable.\n");
1316 }
1317 
1318 /* ARGSUSED */
1319 static int
i915_gem_fence_regs_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1320 i915_gem_fence_regs_info(uintptr_t addr, uint_t flags, int argc,
1321     const mdb_arg_t *argv)
1322 {
1323 	struct drm_i915_private *dev_priv;
1324 	int i, ret = DCMD_OK;
1325 	struct drm_i915_gem_object obj;
1326 
1327 	if (flags & DCMD_ADDRSPEC) {
1328 		mdb_printf("don't need to set address 0x%lx\n", addr);
1329 		return (DCMD_OK);
1330 	}
1331 
1332 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1333 	ret = get_i915_private(dev_priv);
1334 	if (ret != DCMD_OK) {
1335 		goto err;
1336 	}
1337 
1338 	mdb_printf("Reserved fences start = %d\n", dev_priv->fence_reg_start);
1339 	mdb_printf("Total fences = %d\n", dev_priv->num_fence_regs);
1340 
1341 	for (i = 0; i < dev_priv->num_fence_regs; i++) {
1342 
1343 		mdb_printf("Fence %d, pin count = %d, object = ",
1344 		    i, dev_priv->fence_regs[i].pin_count);
1345 
1346 		if (dev_priv->fence_regs[i].obj != NULL) {
1347 			mdb_vread(&obj, sizeof (struct drm_i915_gem_object),
1348 			    (uintptr_t)dev_priv->fence_regs[i].obj);
1349 			describe_obj(&obj);
1350 		} else {
1351 			mdb_printf("unused");
1352 		}
1353 		mdb_printf("\n");
1354 	}
1355 
1356 err:
1357 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1358 	return (ret);
1359 
1360 }
1361 
1362 void
i915_interrupt_info_help(void)1363 i915_interrupt_info_help(void)
1364 {
1365 	mdb_printf("Print debug register information\n"
1366 	    "Registers printed:\n"
1367 	    "       IER:\tInterrupt Enable Register\n"
1368 	    "       IIR:\tInterrupt Identity Register\n"
1369 	    "       IMR:\tInterrupt Mask Register\n"
1370 	    "       ISR:\tInterrupt Status Register\n");
1371 }
1372 
1373 /* ARGSUSED */
1374 static int
i915_interrupt_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1375 i915_interrupt_info(uintptr_t addr, uint_t flags, int argc,
1376     const mdb_arg_t *argv)
1377 {
1378 	struct drm_device *dev;
1379 	struct drm_i915_private *dev_priv;
1380 	struct intel_device_info info;
1381 	int pipe, ret = DCMD_OK;
1382 	uint32_t val;
1383 
1384 	if (flags & DCMD_ADDRSPEC) {
1385 		mdb_printf("don't need to set address 0x%lx\n", addr);
1386 		return (DCMD_OK);
1387 	}
1388 
1389 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
1390 	ret = get_drm_dev(dev);
1391 	if (ret == DCMD_ERR)
1392 		goto err1;
1393 
1394 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1395 	ret = get_i915_private(dev_priv);
1396 	if (ret != DCMD_OK) {
1397 		goto err2;
1398 	}
1399 
1400 	if (mdb_vread(&info, sizeof (struct intel_device_info),
1401 	    (uintptr_t)dev_priv->info) == -1) {
1402 		mdb_warn("failed to read i915 chip info");
1403 		ret = DCMD_ERR;
1404 		goto err2;
1405 	}
1406 
1407 	if (info.is_valleyview) {
1408 		ret = i915_read(dev_priv, (uintptr_t)VLV_IER, &val);
1409 		if (ret == DCMD_OK)
1410 			mdb_printf("Display IER:\t%08x\n", val);
1411 
1412 		ret = i915_read(dev_priv, (uintptr_t)VLV_IIR, &val);
1413 		if (ret == DCMD_OK)
1414 			mdb_printf("Display IIR:\t%08x\n", val);
1415 
1416 		ret = i915_read(dev_priv, (uintptr_t)VLV_IIR_RW, &val);
1417 		if (ret == DCMD_OK)
1418 			mdb_printf("Display IIR_RW:\t%08x\n", val);
1419 
1420 		ret = i915_read(dev_priv, (uintptr_t)VLV_IMR, &val);
1421 		if (ret == DCMD_OK)
1422 			mdb_printf("Display IMR:\t%08x\n", val);
1423 
1424 		for_each_pipe(pipe) {
1425 			ret = i915_read(dev_priv, PIPESTAT(pipe), &val);
1426 			if (ret == DCMD_OK)
1427 				mdb_printf("Pipe %c stat:\t%08x\n",
1428 				    pipe_name(pipe), val);
1429 		}
1430 		ret = i915_read(dev_priv, (uintptr_t)VLV_MASTER_IER, &val);
1431 		if (ret == DCMD_OK)
1432 			mdb_printf("Master IER:\t%08x\n", val);
1433 
1434 		ret = i915_read(dev_priv, (uintptr_t)GTIER, &val);
1435 		if (ret == DCMD_OK)
1436 			mdb_printf("Render IER:\t%08x\n", val);
1437 
1438 		ret = i915_read(dev_priv, (uintptr_t)GTIIR, &val);
1439 		if (ret == DCMD_OK)
1440 			mdb_printf("Render IIR:\t%08x\n", val);
1441 
1442 		ret = i915_read(dev_priv, (uintptr_t)GTIMR, &val);
1443 		if (ret == DCMD_OK)
1444 			mdb_printf("Render IMR:\t%08x\n", val);
1445 
1446 		ret = i915_read(dev_priv, (uintptr_t)GEN6_PMIER, &val);
1447 		if (ret == DCMD_OK)
1448 			mdb_printf("PM IER:\t\t%08x\n", val);
1449 
1450 		ret = i915_read(dev_priv, (uintptr_t)GEN6_PMIIR, &val);
1451 		if (ret == DCMD_OK)
1452 			mdb_printf("PM IIR:\t\t%08x\n", val);
1453 
1454 		ret = i915_read(dev_priv, (uintptr_t)GEN6_PMIMR, &val);
1455 		if (ret == DCMD_OK)
1456 			mdb_printf("PM IMR:\t\t%08x\n", val);
1457 
1458 		ret = i915_read(dev_priv, (uintptr_t)PORT_HOTPLUG_EN, &val);
1459 		if (ret == DCMD_OK)
1460 			mdb_printf("Port hotplug:\t%08x\n", val);
1461 
1462 		ret = i915_read(dev_priv, (uintptr_t)VLV_DPFLIPSTAT, &val);
1463 		if (ret == DCMD_OK)
1464 			mdb_printf("DPFLIPSTAT:\t%08x\n", val);
1465 
1466 		ret = i915_read(dev_priv, (uintptr_t)DPINVGTT, &val);
1467 		if (ret == DCMD_OK)
1468 			mdb_printf("DPINVGTT:\t%08x\n", val);
1469 	} else if (dev_priv->pch_type == PCH_NONE) {
1470 		ret = i915_read(dev_priv, (uintptr_t)IER, &val);
1471 		if (ret == DCMD_OK)
1472 			mdb_printf("Interrupt enable:    %08x\n", val);
1473 
1474 		ret = i915_read(dev_priv, (uintptr_t)IIR, &val);
1475 		if (ret == DCMD_OK)
1476 			mdb_printf("Interrupt identity:  %08x\n", val);
1477 
1478 		ret = i915_read(dev_priv, (uintptr_t)IMR, &val);
1479 		if (ret == DCMD_OK)
1480 			mdb_printf("Interrupt mask:      %08x\n", val);
1481 
1482 		for_each_pipe(pipe) {
1483 			ret = i915_read(dev_priv, (uintptr_t)PIPESTAT(pipe),
1484 			    &val);
1485 			if (ret == DCMD_OK)
1486 				mdb_printf("Pipe %c stat:         %08x\n",
1487 				    pipe_name(pipe), val);
1488 		}
1489 	} else {
1490 		ret = i915_read(dev_priv, (uintptr_t)DEIER, &val);
1491 		if (ret == DCMD_OK)
1492 			mdb_printf(
1493 			    "North Display Interrupt enable:		%08x\n",
1494 			    val);
1495 
1496 		ret = i915_read(dev_priv, (uintptr_t)DEIIR, &val);
1497 		if (ret == DCMD_OK)
1498 			mdb_printf(
1499 			    "North Display Interrupt identity:	%08x\n", val);
1500 
1501 		ret = i915_read(dev_priv, (uintptr_t)DEIMR, &val);
1502 		if (ret == DCMD_OK)
1503 			mdb_printf(
1504 			    "North Display Interrupt mask:		%08x\n",
1505 			    val);
1506 
1507 		ret = i915_read(dev_priv, (uintptr_t)SDEIER, &val);
1508 		if (ret == DCMD_OK)
1509 			mdb_printf(
1510 			    "South Display Interrupt enable:		%08x\n",
1511 			    val);
1512 
1513 		ret = i915_read(dev_priv, (uintptr_t)SDEIIR, &val);
1514 		if (ret == DCMD_OK)
1515 			mdb_printf(
1516 			    "South Display Interrupt identity:	%08x\n", val);
1517 
1518 		ret = i915_read(dev_priv, (uintptr_t)SDEIMR, &val);
1519 		if (ret == DCMD_OK)
1520 			mdb_printf(
1521 			    "South Display Interrupt mask:		%08x\n",
1522 			    val);
1523 
1524 		ret = i915_read(dev_priv, (uintptr_t)GTIER, &val);
1525 		if (ret == DCMD_OK)
1526 			mdb_printf(
1527 			    "Graphics Interrupt enable:		%08x\n", val);
1528 
1529 		ret = i915_read(dev_priv, (uintptr_t)GTIIR, &val);
1530 		if (ret == DCMD_OK)
1531 			mdb_printf(
1532 			    "Graphics Interrupt identity:		%08x\n",
1533 			    val);
1534 
1535 		ret = i915_read(dev_priv, (uintptr_t)GTIMR, &val);
1536 		if (ret == DCMD_OK)
1537 			mdb_printf(
1538 			    "Graphics Interrupt mask:		%08x\n", val);
1539 	}
1540 	mdb_printf("Interrupts received: %d\n", dev_priv->irq_received);
1541 
1542 err2:
1543 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1544 err1:
1545 	mdb_free(dev, sizeof (struct drm_device));
1546 
1547 	return (ret);
1548 
1549 }
1550 
1551 void
i915_hws_info_help(void)1552 i915_hws_info_help(void)
1553 {
1554 	mdb_printf("Print hardware status page for each RING\n");
1555 }
1556 
1557 /* ARGSUSED */
1558 static int
i915_hws_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1559 i915_hws_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1560 {
1561 	struct drm_i915_private *dev_priv;
1562 	int ret = DCMD_OK;
1563 
1564 	if (flags & DCMD_ADDRSPEC) {
1565 		mdb_printf("don't need to set address 0x%lx\n", addr);
1566 		return (DCMD_OK);
1567 	}
1568 
1569 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1570 	ret = get_i915_private(dev_priv);
1571 	if (ret != DCMD_OK) {
1572 		goto err;
1573 	}
1574 
1575 	mdb_printf("Hardware status page for %s\n", "RENDER");
1576 	ret = get_hws_info((uintptr_t)dev_priv->ring[0].status_page.page_addr,
1577 	    "RENDER", -1);
1578 	if (ret != DCMD_OK) {
1579 		goto err;
1580 	}
1581 
1582 	mdb_printf("Hardware status page for %s\n", "BSD");
1583 	ret = get_hws_info((uintptr_t)dev_priv->ring[1].status_page.page_addr,
1584 	    "BSD", -1);
1585 	if (ret != DCMD_OK) {
1586 		goto err;
1587 	}
1588 
1589 	mdb_printf("Hardware status page for %s\n", "BLT");
1590 	ret = get_hws_info((uintptr_t)dev_priv->ring[2].status_page.page_addr,
1591 	    "BLT", -1);
1592 	if (ret != DCMD_OK) {
1593 		goto err;
1594 	}
1595 
1596 err:
1597 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1598 	return (ret);
1599 
1600 }
1601 
1602 void
i915_fbc_status_help(void)1603 i915_fbc_status_help(void)
1604 {
1605 	mdb_printf("Print the status and reason for Framebuffer Compression "
1606 	    "Enabling\n");
1607 }
1608 
1609 /* ARGSUSED */
1610 static int
i915_fbc_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1611 i915_fbc_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1612 {
1613 	struct drm_device *dev;
1614 	struct drm_i915_private *dev_priv;
1615 	struct intel_device_info info;
1616 	int ret = DCMD_OK;
1617 	uint32_t val;
1618 
1619 	if (flags & DCMD_ADDRSPEC) {
1620 		mdb_printf("don't need to set address 0x%lx\n", addr);
1621 		return (DCMD_OK);
1622 	}
1623 
1624 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
1625 	ret = get_drm_dev(dev);
1626 	if (ret == DCMD_ERR)
1627 		goto err1;
1628 
1629 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1630 	ret = get_i915_private(dev_priv);
1631 	if (ret != DCMD_OK) {
1632 		goto err2;
1633 	}
1634 
1635 	if (mdb_vread(&info, sizeof (struct intel_device_info),
1636 	    (uintptr_t)dev_priv->info) == -1) {
1637 		mdb_warn("failed to read i915 chip info");
1638 		ret = DCMD_ERR;
1639 		goto err2;
1640 	}
1641 
1642 	if (!info.has_fbc) {
1643 		mdb_printf("FBC unsupported on this chipset\n");
1644 		goto err2;
1645 	}
1646 
1647 	if (dev_priv->pch_type != PCH_NONE) {
1648 		ret = i915_read(dev_priv, (uintptr_t)ILK_DPFC_CONTROL, &val);
1649 		if (ret == DCMD_OK) {
1650 			val &= DPFC_CTL_EN;
1651 		} else {
1652 			mdb_printf("Failed to read FBC register\n");
1653 			goto err2;
1654 		}
1655 	} else if (IS_GM45(dev)) {
1656 		ret = i915_read(dev_priv, (uintptr_t)DPFC_CONTROL, &val);
1657 		if (ret == DCMD_OK) {
1658 			val &= DPFC_CTL_EN;
1659 		} else {
1660 			mdb_printf("Failed to read FBC register\n");
1661 			goto err2;
1662 		}
1663 	} else if (info.is_crestline) {
1664 		ret = i915_read(dev_priv, (uintptr_t)FBC_CONTROL, &val);
1665 		if (ret == DCMD_OK) {
1666 			val &= FBC_CTL_EN;
1667 		} else {
1668 			mdb_printf("Failed to read FBC register\n");
1669 			goto err2;
1670 		}
1671 	}
1672 
1673 	if (val) {
1674 		mdb_printf("FBC enabled\n");
1675 	} else {
1676 		mdb_printf("FBC disabled: ");
1677 		switch (dev_priv->no_fbc_reason) {
1678 		case FBC_NO_OUTPUT:
1679 			mdb_printf("no outputs");
1680 			break;
1681 		case FBC_STOLEN_TOO_SMALL:
1682 			mdb_printf("not enough stolen memory");
1683 			break;
1684 		case FBC_UNSUPPORTED_MODE:
1685 			mdb_printf("mode not supported");
1686 			break;
1687 		case FBC_MODE_TOO_LARGE:
1688 			mdb_printf("mode too large");
1689 			break;
1690 		case FBC_BAD_PLANE:
1691 			mdb_printf("FBC unsupported on plane");
1692 			break;
1693 		case FBC_NOT_TILED:
1694 			mdb_printf("scanout buffer not tiled");
1695 			break;
1696 		case FBC_MULTIPLE_PIPES:
1697 			mdb_printf("multiple pipes are enabled");
1698 			break;
1699 		case FBC_MODULE_PARAM:
1700 			mdb_printf("disabled per module param (default off)");
1701 			break;
1702 		default:
1703 			mdb_printf("unknown reason");
1704 		}
1705 		mdb_printf("\n");
1706 	}
1707 
1708 err2:
1709 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1710 err1:
1711 	mdb_free(dev, sizeof (struct drm_device));
1712 
1713 	return (ret);
1714 }
1715 
1716 /* ARGSUSED */
1717 static int
i915_sr_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1718 i915_sr_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1719 {
1720 	struct drm_device *dev;
1721 	struct drm_i915_private *dev_priv;
1722 	struct intel_device_info info;
1723 	int ret = DCMD_OK;
1724 	uint32_t val = 0;
1725 
1726 	if (flags & DCMD_ADDRSPEC) {
1727 		mdb_printf("don't need to set address 0x%lx\n", addr);
1728 		return (DCMD_OK);
1729 	}
1730 
1731 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
1732 	ret = get_drm_dev(dev);
1733 	if (ret == DCMD_ERR)
1734 		goto err1;
1735 
1736 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1737 	ret = get_i915_private(dev_priv);
1738 	if (ret != DCMD_OK) {
1739 		goto err2;
1740 	}
1741 
1742 	if (mdb_vread(&info, sizeof (struct intel_device_info),
1743 	    (uintptr_t)dev_priv->info) == -1) {
1744 		mdb_warn("failed to read i915 chip info");
1745 		ret = DCMD_ERR;
1746 		goto err2;
1747 	}
1748 
1749 	if (dev_priv->pch_type != PCH_NONE) {
1750 		ret = i915_read(dev_priv, (uintptr_t)WM1_LP_ILK, &val);
1751 		if (ret == DCMD_OK) {
1752 			val &= WM1_LP_SR_EN;
1753 		} else {
1754 			mdb_printf("Failed to read sr register\n");
1755 			goto err2;
1756 		}
1757 	} else if (info.is_crestline || IS_I945G(dev) || info.is_i945gm) {
1758 		ret = i915_read(dev_priv, (uintptr_t)FW_BLC_SELF, &val);
1759 		if (ret == DCMD_OK) {
1760 			val &= FW_BLC_SELF_EN;
1761 		} else {
1762 			mdb_printf("Failed to read sr register\n");
1763 			goto err2;
1764 		}
1765 	} else if (IS_I915GM(dev)) {
1766 		ret = i915_read(dev_priv, (uintptr_t)INSTPM, &val);
1767 		if (ret == DCMD_OK) {
1768 			val &= INSTPM_SELF_EN;
1769 		} else {
1770 			mdb_printf("Failed to read sr register\n");
1771 			goto err2;
1772 		}
1773 	} else if (info.is_pineview) {
1774 		ret = i915_read(dev_priv, (uintptr_t)DSPFW3, &val);
1775 		if (ret == DCMD_OK) {
1776 			val &= PINEVIEW_SELF_REFRESH_EN;
1777 		} else {
1778 			mdb_printf("Failed to read sr register\n");
1779 			goto err2;
1780 		}
1781 	}
1782 
1783 	mdb_printf("self-refresh: %s\n",
1784 	    val ? "enabled" : "disabled");
1785 
1786 err2:
1787 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1788 err1:
1789 	mdb_free(dev, sizeof (struct drm_device));
1790 
1791 	return (ret);
1792 }
1793 
1794 void
i915_gem_framebuffer_info_help(void)1795 i915_gem_framebuffer_info_help(void)
1796 {
1797 	mdb_printf("Print console framebuffer information\n"
1798 	    "The information includes width, height, depth,\n"
1799 	    "bits_per_pixel and object structure address\n");
1800 }
1801 
1802 /* ARGSUSED */
1803 static int
i915_gem_framebuffer_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1804 i915_gem_framebuffer_info(uintptr_t addr, uint_t flags, int argc,
1805     const mdb_arg_t *argv)
1806 {
1807 	struct drm_device *dev;
1808 	struct drm_i915_private *dev_priv;
1809 	struct intel_fbdev fbdev;
1810 	struct drm_framebuffer fb;
1811 	int ret = DCMD_OK;
1812 
1813 	if (flags & DCMD_ADDRSPEC) {
1814 		mdb_printf("don't need to set address 0x%lx\n", addr);
1815 		return (DCMD_OK);
1816 	}
1817 
1818 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
1819 	ret = get_drm_dev(dev);
1820 	if (ret == DCMD_ERR)
1821 		goto err1;
1822 
1823 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1824 	ret = get_i915_private(dev_priv);
1825 	if (ret != DCMD_OK) {
1826 		goto err2;
1827 	}
1828 
1829 	if (mdb_vread(&fbdev, sizeof (struct intel_fbdev),
1830 	    (uintptr_t)dev_priv->fbdev) == -1) {
1831 		mdb_warn("failed to read intel_fbdev info");
1832 		ret = DCMD_ERR;
1833 		goto err2;
1834 	}
1835 
1836 	if (mdb_vread(&fb, sizeof (struct drm_framebuffer),
1837 	    (uintptr_t)fbdev.helper.fb) == -1) {
1838 		mdb_warn("failed to read framebuffer info");
1839 		ret = DCMD_ERR;
1840 		goto err2;
1841 	}
1842 
1843 	mdb_printf("fbcon size: %d x %d, depth %d, %d bpp, obj %p",
1844 	    fb.width,
1845 	    fb.height,
1846 	    fb.depth,
1847 	    fb.bits_per_pixel,
1848 	    fb.base);
1849 	mdb_printf("\n");
1850 
1851 err2:
1852 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1853 err1:
1854 	mdb_free(dev, sizeof (struct drm_device));
1855 
1856 	return (ret);
1857 }
1858 
1859 /* ARGSUSED */
1860 static int
i915_gen6_forcewake_count_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1861 i915_gen6_forcewake_count_info(uintptr_t addr, uint_t flags, int argc,
1862     const mdb_arg_t *argv)
1863 {
1864 	struct drm_i915_private *dev_priv;
1865 	int ret = DCMD_OK;
1866 	unsigned forcewake_count;
1867 
1868 	if (flags & DCMD_ADDRSPEC) {
1869 		mdb_printf("don't need to set address 0x%lx\n", addr);
1870 		return (DCMD_OK);
1871 	}
1872 
1873 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1874 	ret = get_i915_private(dev_priv);
1875 	if (ret != DCMD_OK) {
1876 		goto err;
1877 	}
1878 
1879 	forcewake_count = dev_priv->forcewake_count;
1880 
1881 	mdb_printf("forcewake count = %u\n", forcewake_count);
1882 
1883 err:
1884 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
1885 
1886 	return (ret);
1887 }
1888 
swizzle_string(unsigned swizzle)1889 static const char *swizzle_string(unsigned swizzle)
1890 {
1891 	switch (swizzle) {
1892 	case I915_BIT_6_SWIZZLE_NONE:
1893 		return ("none");
1894 	case I915_BIT_6_SWIZZLE_9:
1895 		return ("bit9");
1896 	case I915_BIT_6_SWIZZLE_9_10:
1897 		return ("bit9/bit10");
1898 	case I915_BIT_6_SWIZZLE_9_11:
1899 		return ("bit9/bit11");
1900 	case I915_BIT_6_SWIZZLE_9_10_11:
1901 		return ("bit9/bit10/bit11");
1902 	case I915_BIT_6_SWIZZLE_9_17:
1903 		return ("bit9/bit17");
1904 	case I915_BIT_6_SWIZZLE_9_10_17:
1905 		return ("bit9/bit10/bit17");
1906 	case I915_BIT_6_SWIZZLE_UNKNOWN:
1907 		return ("unkown");
1908 	}
1909 
1910 	return ("bug");
1911 }
1912 
1913 void
i915_swizzle_info_help(void)1914 i915_swizzle_info_help(void)
1915 {
1916 	mdb_printf("Print object swizzle information\n"
1917 	    "Registers printed:\n"
1918 	    "       TILECTL:\tTile Control\n"
1919 	    "       ARB_MODE:\tArbiter Mode Control Register\n"
1920 	    "       DISP_ARB_CTL:\tDisplay Arbiter Control\n");
1921 
1922 }
1923 
1924 /* ARGSUSED */
1925 static int
i915_swizzle_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1926 i915_swizzle_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1927 {
1928 	struct drm_device *dev;
1929 	struct drm_i915_private *dev_priv;
1930 	struct intel_device_info info;
1931 	int ret = DCMD_OK;
1932 	uint32_t val = 0;
1933 
1934 	if (flags & DCMD_ADDRSPEC) {
1935 		mdb_printf("don't need to set address 0x%lx\n", addr);
1936 		return (DCMD_OK);
1937 	}
1938 
1939 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
1940 	ret = get_drm_dev(dev);
1941 	if (ret == DCMD_ERR)
1942 		goto err1;
1943 
1944 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
1945 	ret = get_i915_private(dev_priv);
1946 	if (ret != DCMD_OK) {
1947 		goto err2;
1948 	}
1949 
1950 	if (mdb_vread(&info, sizeof (struct intel_device_info),
1951 	    (uintptr_t)dev_priv->info) == -1) {
1952 		mdb_warn("failed to read i915 chip info");
1953 		ret = DCMD_ERR;
1954 		goto err2;
1955 	}
1956 
1957 	mdb_printf("bit6 swizzle for X-tiling = %s\n",
1958 	    swizzle_string(dev_priv->mm.bit_6_swizzle_x));
1959 	mdb_printf("bit6 swizzle for Y-tiling = %s\n",
1960 	    swizzle_string(dev_priv->mm.bit_6_swizzle_y));
1961 
1962 	if ((info.gen == 3) || (info.gen == 4)) {
1963 		ret = i915_read(dev_priv, (uintptr_t)DCC, &val);
1964 		if (ret == DCMD_OK)
1965 			mdb_printf("DDC = 0x%08x\n", val);
1966 
1967 		ret = i915_read(dev_priv, (uintptr_t)C0DRB3, &val);
1968 		if (ret == DCMD_OK)
1969 			mdb_printf("C0DRB3 = 0x%04x\n", val);
1970 
1971 		ret = i915_read(dev_priv, (uintptr_t)C1DRB3, &val);
1972 		if (ret == DCMD_OK)
1973 			mdb_printf("C1DRB3 = 0x%04x\n", val);
1974 
1975 	} else if ((info.gen == 6) || (info.gen == 7)) {
1976 		ret = i915_read(dev_priv, (uintptr_t)MAD_DIMM_C0, &val);
1977 		if (ret == DCMD_OK)
1978 			mdb_printf("MAD_DIMM_C0 = 0x%08x\n", val);
1979 
1980 		ret = i915_read(dev_priv, (uintptr_t)MAD_DIMM_C1, &val);
1981 		if (ret == DCMD_OK)
1982 			mdb_printf("MAD_DIMM_C1 = 0x%08x\n", val);
1983 
1984 		ret = i915_read(dev_priv, (uintptr_t)MAD_DIMM_C2, &val);
1985 		if (ret == DCMD_OK)
1986 			mdb_printf("MAD_DIMM_C2 = 0x%08x\n", val);
1987 
1988 		ret = i915_read(dev_priv, (uintptr_t)TILECTL, &val);
1989 		if (ret == DCMD_OK)
1990 			mdb_printf("TILECTL = 0x%08x\n", val);
1991 
1992 		ret = i915_read(dev_priv, (uintptr_t)ARB_MODE, &val);
1993 		if (ret == DCMD_OK)
1994 			mdb_printf("ARB_MODE = 0x%08x\n", val);
1995 
1996 		ret = i915_read(dev_priv, (uintptr_t)DISP_ARB_CTL, &val);
1997 		if (ret == DCMD_OK)
1998 			mdb_printf("DISP_ARB_CTL = 0x%08x\n", val);
1999 
2000 	}
2001 
2002 err2:
2003 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
2004 err1:
2005 	mdb_free(dev, sizeof (struct drm_device));
2006 
2007 	return (ret);
2008 }
2009 
2010 void
i915_ppgtt_info_help(void)2011 i915_ppgtt_info_help(void)
2012 {
2013 	mdb_printf("Print Per-Process GTT (PPGTT) information\n"
2014 	    "Registers printed:\n"
2015 	    "       GFX_MODE:\tGraphics Mode Register\n"
2016 	    "       PP_DIR_BASE:\tPage Directory Base Register\n"
2017 	    "       ECOCHK:\tMain Graphic Arbiter Misc Register\n");
2018 }
2019 
2020 /* ARGSUSED */
2021 static int
i915_ppgtt_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2022 i915_ppgtt_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2023 {
2024 	struct drm_device *dev;
2025 	struct drm_i915_private *dev_priv;
2026 	struct intel_device_info info;
2027 	int i, ret = DCMD_OK;
2028 	uint32_t val = 0;
2029 
2030 	if (flags & DCMD_ADDRSPEC) {
2031 		mdb_printf("don't need to set address 0x%lx\n", addr);
2032 		return (DCMD_OK);
2033 	}
2034 
2035 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
2036 	ret = get_drm_dev(dev);
2037 	if (ret == DCMD_ERR)
2038 		goto err1;
2039 
2040 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
2041 	ret = get_i915_private(dev_priv);
2042 	if (ret != DCMD_OK) {
2043 		goto err2;
2044 	}
2045 
2046 	if (mdb_vread(&info, sizeof (struct intel_device_info),
2047 	    (uintptr_t)dev_priv->info) == -1) {
2048 		mdb_warn("failed to read i915 chip info");
2049 		ret = DCMD_ERR;
2050 		goto err2;
2051 	}
2052 
2053 	if (info.gen == 6) {
2054 		ret = i915_read(dev_priv, (uintptr_t)GFX_MODE, &val);
2055 		if (ret == DCMD_OK)
2056 			mdb_printf("GFX_MODE: 0x%08x\n", val);
2057 	}
2058 
2059 	for (i = 0; i < 3; i ++) {
2060 		mdb_printf("RING %d\n", i);
2061 		if (info.gen == 7) {
2062 			ret = i915_read(dev_priv,
2063 			    (uintptr_t)(dev_priv->ring[i].mmio_base + 0x29c),
2064 			    &val);
2065 			if (ret == DCMD_OK)
2066 				mdb_printf("GFX_MODE: 0x%08x\n", val);
2067 		}
2068 		ret = i915_read(dev_priv,
2069 		    (uintptr_t)(dev_priv->ring[i].mmio_base + 0x228), &val);
2070 		if (ret == DCMD_OK)
2071 			mdb_printf("PP_DIR_BASE: 0x%08x\n", val);
2072 
2073 		ret = i915_read(dev_priv,
2074 		    (uintptr_t)(dev_priv->ring[i].mmio_base + 0x518), &val);
2075 		if (ret == DCMD_OK)
2076 			mdb_printf("PP_DIR_BASE_READ: 0x%08x\n", val);
2077 
2078 		ret = i915_read(dev_priv,
2079 		    (uintptr_t)(dev_priv->ring[i].mmio_base + 0x220), &val);
2080 		if (ret == DCMD_OK)
2081 			mdb_printf("PP_DIR_DCLV: 0x%08x\n", val);
2082 	}
2083 
2084 	if (dev_priv->mm.aliasing_ppgtt) {
2085 		struct i915_hw_ppgtt ppgtt;
2086 		if (mdb_vread(&ppgtt, sizeof (struct i915_hw_ppgtt),
2087 		    (uintptr_t)dev_priv->mm.aliasing_ppgtt) == -1) {
2088 			mdb_warn("failed to read aliasing_ppgtt info");
2089 			ret = DCMD_ERR;
2090 			goto err2;
2091 		}
2092 
2093 		mdb_printf("aliasing PPGTT:\n");
2094 		mdb_printf("pd gtt offset: 0x%08x\n", ppgtt.pd_offset);
2095 	}
2096 
2097 	ret = i915_read(dev_priv, (uintptr_t)GAM_ECOCHK, &val);
2098 	if (ret == DCMD_OK)
2099 		mdb_printf("ECOCHK: 0x%08x\n", val);
2100 
2101 err2:
2102 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
2103 err1:
2104 	mdb_free(dev, sizeof (struct drm_device));
2105 
2106 	return (ret);
2107 }
2108 
2109 /*
2110  * MDB module linkage information:
2111  *
2112  * We declare a list of structures describing our dcmds, a list of structures
2113  * describing our walkers, and a function named _mdb_init to return a pointer
2114  * to our module information.
2115  */
2116 
2117 static const mdb_dcmd_t dcmds[] = {
2118 	{
2119 		"i915_pciid",
2120 		"?",
2121 		"pciid information",
2122 		i915_pciid,
2123 		i915_pciid_help
2124 	},
2125 	{
2126 		"i915_gtt_total",
2127 		"?",
2128 		"get gtt total size",
2129 		i915_gtt_total,
2130 		i915_gtt_total_help
2131 	},
2132 	{
2133 		"i915_obj_list",
2134 		"[-aibu]",
2135 		"i915 objects list information",
2136 		i915_obj_list,
2137 		i915_obj_list_help
2138 	},
2139 	{
2140 		"i915_obj_list_node",
2141 		":",
2142 		"i915 objects list node information",
2143 		i915_obj_list_node,
2144 		i915_obj_list_node_help
2145 	},
2146 	{
2147 		"i915_ringbuffer_info",
2148 		"[-lrs]",
2149 		"i915 ring buffer information",
2150 		i915_ringbuffer_info,
2151 		i915_ringbuffer_info_help
2152 	},
2153 	{
2154 		"i915_gtt_dump",
2155 		"?",
2156 		"dump gtt_dump_add address",
2157 		i915_gtt_dump,
2158 		i915_gtt_dump_help
2159 	},
2160 	{
2161 		"i915_register_read",
2162 		":",
2163 		"read i915 register",
2164 		i915_register_read,
2165 		i915_register_read_help
2166 	},
2167 	{
2168 		"i915_error_reg_dump",
2169 		"?",
2170 		"i915 error registers dump",
2171 		i915_error_reg_dump,
2172 		i915_error_reg_dump_help
2173 	},
2174 	{
2175 		"i915_obj_history",
2176 		":",
2177 		"i915 objects track information",
2178 		i915_obj_history,
2179 		i915_obj_history_help
2180 	},
2181 	{
2182 		"i915_batch_history",
2183 		"?",
2184 		"i915 objects track information",
2185 		i915_batch_history,
2186 		i915_batch_history_help
2187 	},
2188 	{
2189 		"i915_capabilities",
2190 		"?",
2191 		"i915 capabilities information",
2192 		i915_capabilities,
2193 		i915_capabilities_help
2194 	},
2195 	{
2196 		"i915_request_list_node",
2197 		":",
2198 		"i915 request list node information",
2199 		i915_request_list_node,
2200 		i915_request_list_node_help
2201 	},
2202 	{
2203 		"i915_gem_request",
2204 		"?",
2205 		"i915 gem request information",
2206 		i915_gem_request_info,
2207 		i915_gem_request_info_help
2208 	},
2209 	{
2210 		"i915_ring_seqno",
2211 		"?",
2212 		"ring seqno information",
2213 		i915_ring_seqno_info,
2214 		i915_ring_seqno_info_help
2215 	},
2216 	{
2217 		"i915_gem_fence_regs",
2218 		"?",
2219 		"fence register information",
2220 		i915_gem_fence_regs_info,
2221 		i915_gem_fence_regs_info_help
2222 	},
2223 	{
2224 		"i915_interrupt",
2225 		"?",
2226 		"interrupt information",
2227 		i915_interrupt_info,
2228 		i915_interrupt_info_help
2229 	},
2230 	{
2231 		"i915_gem_hws",
2232 		"?",
2233 		"hardware status page",
2234 		i915_hws_info,
2235 		i915_hws_info_help
2236 	},
2237 	{
2238 		"i915_fbc_status",
2239 		"?",
2240 		"framebuffer compression information",
2241 		i915_fbc_status,
2242 		i915_fbc_status_help
2243 	},
2244 	{
2245 		"i915_sr_status",
2246 		"?",
2247 		"Print self-refresh status",
2248 		i915_sr_status,
2249 		NULL
2250 	},
2251 	{
2252 		"i915_gem_framebuffer",
2253 		"?",
2254 		"Print framebuffer information",
2255 		i915_gem_framebuffer_info,
2256 		i915_gem_framebuffer_info_help
2257 	},
2258 	{
2259 		"i915_gen6_forcewake_count",
2260 		"?",
2261 		"Print forcewake count",
2262 		i915_gen6_forcewake_count_info,
2263 		NULL
2264 	},
2265 	{
2266 		"i915_swizzle",
2267 		"?",
2268 		"Print swizzle information",
2269 		i915_swizzle_info,
2270 		i915_swizzle_info_help
2271 	},
2272 	{
2273 		"i915_ppgtt",
2274 		"?",
2275 		"Print ppgtt information",
2276 		i915_ppgtt_info,
2277 		i915_ppgtt_info_help
2278 	},
2279 
2280 	{ NULL }
2281 };
2282 
2283 static const mdb_walker_t walkers[] = {
2284 	{
2285 		"head_list",
2286 		"walk head list",
2287 		head_list_walk_init,
2288 		head_list_walk_step,
2289 		head_list_walk_fini
2290 	},
2291 	{ NULL }
2292 };
2293 
2294 static const mdb_modinfo_t modinfo = {
2295 	MDB_API_VERSION, dcmds, walkers
2296 };
2297 
2298 const mdb_modinfo_t *
_mdb_init(void)2299 _mdb_init(void)
2300 {
2301 	return (&modinfo);
2302 }
2303