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(®s, 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