xref: /gfx-drm/usr/src/cmd/mdb/i915/i915.c (revision e1cb3391)
147dc10d7SGordon Ross /*
247dc10d7SGordon Ross  * Copyright (c) 2012, 2013, Intel Corporation.
347dc10d7SGordon Ross  * All Rights Reserved.
447dc10d7SGordon Ross  */
547dc10d7SGordon Ross /*
647dc10d7SGordon Ross  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
747dc10d7SGordon Ross  *
847dc10d7SGordon Ross  * Permission is hereby granted, free of charge, to any person obtaining a
947dc10d7SGordon Ross  * copy of this software and associated documentation files (the "Software"),
1047dc10d7SGordon Ross  * to deal in the Software without restriction, including without limitation
1147dc10d7SGordon Ross  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1247dc10d7SGordon Ross  * and/or sell copies of the Software, and to permit persons to whom the
1347dc10d7SGordon Ross  * Software is furnished to do so, subject to the following conditions:
1447dc10d7SGordon Ross  *
1547dc10d7SGordon Ross  * The above copyright notice and this permission notice (including the next
1647dc10d7SGordon Ross  * paragraph) shall be included in all copies or substantial portions of the
1747dc10d7SGordon Ross  * Software.
1847dc10d7SGordon Ross  *
1947dc10d7SGordon Ross  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2047dc10d7SGordon Ross  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2147dc10d7SGordon Ross  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2247dc10d7SGordon Ross  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2347dc10d7SGordon Ross  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2447dc10d7SGordon Ross  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2547dc10d7SGordon Ross  * DEALINGS IN THE SOFTWARE.
2647dc10d7SGordon Ross  */
2747dc10d7SGordon Ross 
2847dc10d7SGordon Ross #include <sys/mdb_modapi.h>
2947dc10d7SGordon Ross #include <sys/proc.h>
3047dc10d7SGordon Ross 
3134389f68SGordon Ross #include <drm/drmP.h>
3234389f68SGordon Ross #include <drm/i915_drm.h>
3334389f68SGordon Ross #include "i915_drv.h"
3434389f68SGordon Ross #include "intel_drv.h"
3547dc10d7SGordon Ross 
3647dc10d7SGordon Ross 
3747dc10d7SGordon Ross /*
3847dc10d7SGordon Ross  * Defines
3947dc10d7SGordon Ross  */
4047dc10d7SGordon Ross /* dcmd options */
4147dc10d7SGordon Ross #define	ACTIVE_LIST	0x01
4247dc10d7SGordon Ross #define	INACTIVE_LIST	0x02
4347dc10d7SGordon Ross #define	BOUND_LIST	0x04
4447dc10d7SGordon Ross #define	UNBOUND_LIST	0x08
4547dc10d7SGordon Ross 
4647dc10d7SGordon Ross #define	RENDER_RING	0x01
4747dc10d7SGordon Ross #define	BLT_RING	0x02
4847dc10d7SGordon Ross #define	BSD_RING	0x04
4947dc10d7SGordon Ross 
5047dc10d7SGordon Ross u32 count, mappable_count, purgeable_count;
5147dc10d7SGordon Ross size_t size, mappable_size, purgeable_size;
5247dc10d7SGordon Ross 
5347dc10d7SGordon Ross /*
5447dc10d7SGordon Ross  * Initialize the proc_t walker by either using the given starting address,
5547dc10d7SGordon Ross  * or reading the value of the kernel's practive pointer.  We also allocate
5647dc10d7SGordon Ross  * a proc_t for storage, and save this using the walk_data pointer.
5747dc10d7SGordon Ross  */
5847dc10d7SGordon Ross static int
head_list_walk_init(mdb_walk_state_t * wsp)5947dc10d7SGordon Ross head_list_walk_init(mdb_walk_state_t *wsp)
6047dc10d7SGordon Ross {
6147dc10d7SGordon Ross 
6247dc10d7SGordon Ross 	if (wsp->walk_addr == NULL) {
6347dc10d7SGordon Ross 		mdb_warn("head is NULL");
6447dc10d7SGordon Ross 		return (WALK_ERR);
6547dc10d7SGordon Ross 	}
6647dc10d7SGordon Ross 
6747dc10d7SGordon Ross 	wsp->walk_data = mdb_alloc(sizeof (struct list_head), UM_SLEEP);
6847dc10d7SGordon Ross 
6947dc10d7SGordon Ross 	if (mdb_vread(wsp->walk_data, sizeof (struct list_head),
7047dc10d7SGordon Ross 	    wsp->walk_addr) == -1) {
7147dc10d7SGordon Ross 		mdb_warn("failed to read list head at %p", wsp->walk_addr);
7247dc10d7SGordon Ross 		return (WALK_DONE);
7347dc10d7SGordon Ross 	}
7447dc10d7SGordon Ross 
7547dc10d7SGordon Ross 	wsp->walk_arg = (void *)wsp->walk_addr;
7647dc10d7SGordon Ross 
7747dc10d7SGordon Ross 	wsp->walk_addr =
7847dc10d7SGordon Ross 	    (uintptr_t)(((struct list_head *)wsp->walk_data)->next);
7947dc10d7SGordon Ross 
8047dc10d7SGordon Ross 	return (WALK_NEXT);
8147dc10d7SGordon Ross }
8247dc10d7SGordon Ross 
8347dc10d7SGordon Ross /*
8447dc10d7SGordon Ross  * At each step, read a proc_t into our private storage, and then invoke
8547dc10d7SGordon Ross  * the callback function.  We terminate when we reach a NULL p_next pointer.
8647dc10d7SGordon Ross  */
8747dc10d7SGordon Ross static int
head_list_walk_step(mdb_walk_state_t * wsp)8847dc10d7SGordon Ross head_list_walk_step(mdb_walk_state_t *wsp)
8947dc10d7SGordon Ross {
9047dc10d7SGordon Ross 	int status;
9147dc10d7SGordon Ross 
9247dc10d7SGordon Ross 	if (wsp->walk_addr == NULL) {
9347dc10d7SGordon Ross 		mdb_warn("uncompletement list");
9447dc10d7SGordon Ross 		return (WALK_DONE);
9547dc10d7SGordon Ross 	}
9647dc10d7SGordon Ross 
9747dc10d7SGordon Ross 	if (mdb_vread(wsp->walk_data, sizeof (struct list_head),
9847dc10d7SGordon Ross 	    wsp->walk_addr) == -1) {
9947dc10d7SGordon Ross 		mdb_warn("failed to read list at %p", wsp->walk_addr);
10047dc10d7SGordon Ross 		return (WALK_DONE);
10147dc10d7SGordon Ross 	}
10247dc10d7SGordon Ross 
10347dc10d7SGordon Ross 	if ((void *)wsp->walk_addr == wsp->walk_arg) {
10447dc10d7SGordon Ross 		return (WALK_DONE);
10547dc10d7SGordon Ross 	}
10647dc10d7SGordon Ross 
10747dc10d7SGordon Ross 	status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
10847dc10d7SGordon Ross 	    wsp->walk_cbdata);
10947dc10d7SGordon Ross 
11047dc10d7SGordon Ross 	wsp->walk_addr =
11147dc10d7SGordon Ross 	    (uintptr_t)(((struct list_head *)wsp->walk_data)->next);
11247dc10d7SGordon Ross 	return (status);
11347dc10d7SGordon Ross }
11447dc10d7SGordon Ross 
11547dc10d7SGordon Ross /*
11647dc10d7SGordon Ross  * The walker's fini function is invoked at the end of each walk.  Since we
11747dc10d7SGordon Ross  * dynamically allocated a proc_t in sp_walk_init, we must free it now.
11847dc10d7SGordon Ross  */
11947dc10d7SGordon Ross static void
head_list_walk_fini(mdb_walk_state_t * wsp)12047dc10d7SGordon Ross head_list_walk_fini(mdb_walk_state_t *wsp)
12147dc10d7SGordon Ross {
12247dc10d7SGordon Ross 	mdb_free(wsp->walk_data, sizeof (proc_t));
12347dc10d7SGordon Ross }
12447dc10d7SGordon Ross 
12547dc10d7SGordon Ross static int
get_drm_dev(struct drm_device * drm_dev)12647dc10d7SGordon Ross get_drm_dev(struct drm_device *drm_dev)
12747dc10d7SGordon Ross {
12847dc10d7SGordon Ross 	uintptr_t i915_ss;
12947dc10d7SGordon Ross 	void *state;
13047dc10d7SGordon Ross 	i_ddi_soft_state *ss;
13147dc10d7SGordon Ross 	uintptr_t array;
13247dc10d7SGordon Ross 
13347dc10d7SGordon Ross 	state = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
13447dc10d7SGordon Ross 
13547dc10d7SGordon Ross 	if (mdb_readsym(&i915_ss, sizeof (i915_ss),
13647dc10d7SGordon Ross 	    "i915_statep") == -1) {
13747dc10d7SGordon Ross 		mdb_warn("failed to read i915_statep");
13847dc10d7SGordon Ross 		mdb_free(state, sizeof (struct drm_device));
13947dc10d7SGordon Ross 		return (-1);
14047dc10d7SGordon Ross 	}
14147dc10d7SGordon Ross 
14247dc10d7SGordon Ross 	if (mdb_vread(state, sizeof (struct drm_device), i915_ss) == -1) {
14347dc10d7SGordon Ross 		mdb_warn("Failed to read state\n");
14447dc10d7SGordon Ross 		mdb_free(state, sizeof (struct drm_device));
14547dc10d7SGordon Ross 		return (-1);
14647dc10d7SGordon Ross 	}
14747dc10d7SGordon Ross 
14847dc10d7SGordon Ross 	ss = (i_ddi_soft_state *) state;
14947dc10d7SGordon Ross 
15047dc10d7SGordon Ross 	if (mdb_vread(&array, sizeof (uintptr_t), (uintptr_t)ss->array) == -1) {
15147dc10d7SGordon Ross 		mdb_warn("Failed to read array\n");
15247dc10d7SGordon Ross 		mdb_free(state, sizeof (struct drm_device));
15347dc10d7SGordon Ross 		return (-1);
15447dc10d7SGordon Ross 	}
15547dc10d7SGordon Ross 
15647dc10d7SGordon Ross 	if (mdb_vread(drm_dev, sizeof (struct drm_device), array) == -1) {
15747dc10d7SGordon Ross 		mdb_warn("Failed to read drm_dev\n");
15847dc10d7SGordon Ross 		mdb_free(state, sizeof (struct drm_device));
15947dc10d7SGordon Ross 		return (-1);
16047dc10d7SGordon Ross 	}
16147dc10d7SGordon Ross 	mdb_free(state, sizeof (struct drm_device));
16247dc10d7SGordon Ross 
16347dc10d7SGordon Ross 	return (DCMD_OK);
16447dc10d7SGordon Ross }
16547dc10d7SGordon Ross 
16647dc10d7SGordon Ross static int
get_i915_private(struct drm_i915_private * dev_priv)16747dc10d7SGordon Ross get_i915_private(struct drm_i915_private *dev_priv)
16847dc10d7SGordon Ross {
16947dc10d7SGordon Ross 	struct drm_device *drm_dev;
17047dc10d7SGordon Ross 	int ret;
17147dc10d7SGordon Ross 
17247dc10d7SGordon Ross 	drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
17347dc10d7SGordon Ross 	ret = get_drm_dev(drm_dev);
17447dc10d7SGordon Ross 
17547dc10d7SGordon Ross 	if (ret == DCMD_OK) {
17647dc10d7SGordon Ross 		if (mdb_vread(dev_priv, sizeof (struct drm_i915_private),
17747dc10d7SGordon Ross 		    (uintptr_t)drm_dev->dev_private) == -1) {
17847dc10d7SGordon Ross 			mdb_warn("Failed to read i915 private\n");
17947dc10d7SGordon Ross 			mdb_free(drm_dev, sizeof (struct drm_device));
18047dc10d7SGordon Ross 			return (-1);
18147dc10d7SGordon Ross 		}
18247dc10d7SGordon Ross 	}
18347dc10d7SGordon Ross 	mdb_free(drm_dev, sizeof (struct drm_device));
18447dc10d7SGordon Ross 	return (ret);
18547dc10d7SGordon Ross }
18647dc10d7SGordon Ross 
18747dc10d7SGordon Ross void
i915_pciid_help(void)18847dc10d7SGordon Ross i915_pciid_help(void)
18947dc10d7SGordon Ross {
19047dc10d7SGordon Ross 	mdb_printf("Print device ID information of Intel graphics card.\n");
19147dc10d7SGordon Ross }
19247dc10d7SGordon Ross 
19347dc10d7SGordon Ross /* ARGSUSED */
19447dc10d7SGordon Ross static int
i915_pciid(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)19547dc10d7SGordon Ross i915_pciid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
19647dc10d7SGordon Ross {
19747dc10d7SGordon Ross 	int ret;
19847dc10d7SGordon Ross 	struct drm_device *drm_dev;
19947dc10d7SGordon Ross 
20047dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
20147dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
20247dc10d7SGordon Ross 		return (DCMD_OK);
20347dc10d7SGordon Ross 	}
20447dc10d7SGordon Ross 
20547dc10d7SGordon Ross 	drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
20647dc10d7SGordon Ross 
20747dc10d7SGordon Ross 	ret = get_drm_dev(drm_dev);
20847dc10d7SGordon Ross 	if (ret == DCMD_OK)
20947dc10d7SGordon Ross 		mdb_printf(" vendor 0x%x device 0x%x\n",
21047dc10d7SGordon Ross 		    drm_dev->pci_vendor, drm_dev->pci_device);
21147dc10d7SGordon Ross 
21247dc10d7SGordon Ross 	mdb_free(drm_dev, sizeof (struct drm_device));
21347dc10d7SGordon Ross 	return (ret);
21447dc10d7SGordon Ross }
21547dc10d7SGordon Ross 
21647dc10d7SGordon Ross void
i915_gtt_total_help(void)21747dc10d7SGordon Ross i915_gtt_total_help(void)
21847dc10d7SGordon Ross {
21947dc10d7SGordon Ross 	mdb_printf("Print graphics translation table (GTT) size\n");
22047dc10d7SGordon Ross }
22147dc10d7SGordon Ross 
22247dc10d7SGordon Ross /* ARGSUSED */
22347dc10d7SGordon Ross static int
i915_gtt_total(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)22447dc10d7SGordon Ross i915_gtt_total(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
22547dc10d7SGordon Ross {
22647dc10d7SGordon Ross 	int ret;
22747dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
22847dc10d7SGordon Ross 
22947dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
23047dc10d7SGordon Ross 
23147dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
23247dc10d7SGordon Ross 	if (ret == DCMD_OK) {
23347dc10d7SGordon Ross 		mdb_printf("gtt total size 0x%x", dev_priv->gtt.total);
23447dc10d7SGordon Ross 		mdb_printf("gtt mappable size 0x%x",
23547dc10d7SGordon Ross 		    dev_priv->gtt.mappable_end);
23647dc10d7SGordon Ross 		mdb_printf("gtt stolen size 0x%x", dev_priv->gtt.stolen_size);
23747dc10d7SGordon Ross 	}
23847dc10d7SGordon Ross 
23947dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
24047dc10d7SGordon Ross 	return (ret);
24147dc10d7SGordon Ross }
24247dc10d7SGordon Ross 
get_pin_flag(struct drm_i915_gem_object * obj)24347dc10d7SGordon Ross static const char *get_pin_flag(struct drm_i915_gem_object *obj)
24447dc10d7SGordon Ross {
24547dc10d7SGordon Ross 	if (obj->user_pin_count > 0)
24647dc10d7SGordon Ross 		return ("P");
24747dc10d7SGordon Ross 	else if (obj->pin_count > 0)
24847dc10d7SGordon Ross 		return ("p");
24947dc10d7SGordon Ross 	else
25047dc10d7SGordon Ross 		return (" ");
25147dc10d7SGordon Ross }
25247dc10d7SGordon Ross 
get_tiling_flag(struct drm_i915_gem_object * obj)25347dc10d7SGordon Ross static const char *get_tiling_flag(struct drm_i915_gem_object *obj)
25447dc10d7SGordon Ross {
25547dc10d7SGordon Ross 	switch (obj->tiling_mode) {
25647dc10d7SGordon Ross 	default:
25747dc10d7SGordon Ross 	case I915_TILING_NONE: return " ";
25847dc10d7SGordon Ross 	case I915_TILING_X: return "X";
25947dc10d7SGordon Ross 	case I915_TILING_Y: return "Y";
26047dc10d7SGordon Ross 	}
26147dc10d7SGordon Ross }
26247dc10d7SGordon Ross 
cache_level_str(int type)26347dc10d7SGordon Ross static const char *cache_level_str(int type)
26447dc10d7SGordon Ross {
26547dc10d7SGordon Ross 	switch (type) {
26647dc10d7SGordon Ross 	case I915_CACHE_NONE: return " uncached";
26747dc10d7SGordon Ross 	case I915_CACHE_LLC: return " snooped (LLC)";
26847dc10d7SGordon Ross 	case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)";
26947dc10d7SGordon Ross 	default: return "";
27047dc10d7SGordon Ross 	}
27147dc10d7SGordon Ross }
27247dc10d7SGordon Ross 
27347dc10d7SGordon Ross static void
describe_obj(struct drm_i915_gem_object * obj)27447dc10d7SGordon Ross describe_obj(struct drm_i915_gem_object *obj)
27547dc10d7SGordon Ross {
27647dc10d7SGordon Ross 
27747dc10d7SGordon Ross 	mdb_printf("%p: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s",
27847dc10d7SGordon Ross 	    &obj->base,
27947dc10d7SGordon Ross 	    get_pin_flag(obj),
28047dc10d7SGordon Ross 	    get_tiling_flag(obj),
28147dc10d7SGordon Ross 	    obj->base.size / 1024,
28247dc10d7SGordon Ross 	    obj->base.read_domains,
28347dc10d7SGordon Ross 	    obj->base.write_domain,
28447dc10d7SGordon Ross 	    obj->last_read_seqno,
28547dc10d7SGordon Ross 	    obj->last_write_seqno,
28647dc10d7SGordon Ross 	    obj->last_fenced_seqno,
28747dc10d7SGordon Ross 	    cache_level_str(obj->cache_level),
28847dc10d7SGordon Ross 	    obj->dirty ? " dirty" : "",
28947dc10d7SGordon Ross 	    obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
29047dc10d7SGordon Ross 	if (obj->base.name)
29147dc10d7SGordon Ross 		mdb_printf(" (name: %d)", obj->base.name);
29247dc10d7SGordon Ross 	if (obj->pin_count)
29347dc10d7SGordon Ross 		mdb_printf(" (pinned x %d)", obj->pin_count);
29447dc10d7SGordon Ross 	if (obj->fence_reg != I915_FENCE_REG_NONE)
29547dc10d7SGordon Ross 		mdb_printf(" (fence: %d)", obj->fence_reg);
29647dc10d7SGordon Ross 	if (obj->gtt_space != NULL)
29747dc10d7SGordon Ross 		mdb_printf(" (gtt offset: %08x, size: %08x)",
29847dc10d7SGordon Ross 		    obj->gtt_offset, (unsigned int)obj->base.real_size);
29947dc10d7SGordon Ross 	if (obj->pin_mappable || obj->fault_mappable) {
30047dc10d7SGordon Ross 		char s[3], *t = s;
30147dc10d7SGordon Ross 		if (obj->pin_mappable)
30247dc10d7SGordon Ross 			*t++ = 'p';
30347dc10d7SGordon Ross 		if (obj->fault_mappable)
30447dc10d7SGordon Ross 			*t++ = 'f';
30547dc10d7SGordon Ross 		*t = '\0';
30647dc10d7SGordon Ross 		mdb_printf(" (%s mappable)", s);
30747dc10d7SGordon Ross 	}
30847dc10d7SGordon Ross 
30947dc10d7SGordon Ross }
31047dc10d7SGordon Ross 
31147dc10d7SGordon Ross static void
i915_obj_info(struct drm_i915_gem_object * obj)31247dc10d7SGordon Ross i915_obj_info(struct drm_i915_gem_object *obj)
31347dc10d7SGordon Ross {
31447dc10d7SGordon Ross 
31547dc10d7SGordon Ross 	/* "size", "gtt_off", "kaddr", "pfn_array" */
31647dc10d7SGordon Ross 
31747dc10d7SGordon Ross 	mdb_printf(" 0x%-8x  0x%-8x  0x%lx  0x%lx\n",
31847dc10d7SGordon Ross 	    obj->base.real_size, obj->gtt_offset, obj->base.kaddr,
31947dc10d7SGordon Ross 	    obj->base.pfnarray);
32047dc10d7SGordon Ross 
32147dc10d7SGordon Ross 	size += obj->base.real_size;
32247dc10d7SGordon Ross 	++count;
32347dc10d7SGordon Ross 	if (obj->map_and_fenceable) {
32447dc10d7SGordon Ross 		mappable_size += obj->base.real_size;
32547dc10d7SGordon Ross 		++mappable_count;
32647dc10d7SGordon Ross 	}
32747dc10d7SGordon Ross 
32847dc10d7SGordon Ross }
32947dc10d7SGordon Ross 
33047dc10d7SGordon Ross void
i915_obj_list_node_help(void)33147dc10d7SGordon Ross i915_obj_list_node_help(void)
33247dc10d7SGordon Ross {
33347dc10d7SGordon Ross 	mdb_printf("Print objects information for a given list pointer\n"
33447dc10d7SGordon Ross 	"Fields printed:\n"
33547dc10d7SGordon Ross 	"       obj:\tpointer to drm_i915_gem_object structure\n"
33647dc10d7SGordon Ross 	"       size:\tobject size\n"
33747dc10d7SGordon Ross 	"       gtt_off:\tobject offset in GTT (graphics address)\n"
33847dc10d7SGordon Ross 	"       kaddr:\tobject kernel virtual address\n"
33947dc10d7SGordon Ross 	"       pfn_array:\tArrary which contains object's PFN\n");
34047dc10d7SGordon Ross }
34147dc10d7SGordon Ross 
34247dc10d7SGordon Ross /* ARGSUSED */
34347dc10d7SGordon Ross static int
i915_obj_list_node(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)34447dc10d7SGordon Ross i915_obj_list_node(uintptr_t addr, uint_t flags, int argc,
34547dc10d7SGordon Ross     const mdb_arg_t *argv)
34647dc10d7SGordon Ross {
34747dc10d7SGordon Ross 	int ret = DCMD_OK;
34847dc10d7SGordon Ross 	struct list_head list;
34947dc10d7SGordon Ross 	struct drm_i915_gem_object *obj;
35047dc10d7SGordon Ross 
35147dc10d7SGordon Ross 	if (!(flags & DCMD_ADDRSPEC))
35247dc10d7SGordon Ross 		return (DCMD_USAGE);
35347dc10d7SGordon Ross 
35447dc10d7SGordon Ross 	if (mdb_vread(&list, sizeof (struct list), addr) == -1) {
35547dc10d7SGordon Ross 		mdb_warn("failed to read list");
35647dc10d7SGordon Ross 		return (DCMD_ERR);
35747dc10d7SGordon Ross 	}
35847dc10d7SGordon Ross 
35947dc10d7SGordon Ross 	if (list.contain_ptr == 0) {
36047dc10d7SGordon Ross 		mdb_warn("no object!");
36147dc10d7SGordon Ross 		return (DCMD_ERR);
36247dc10d7SGordon Ross 	}
36347dc10d7SGordon Ross 
36447dc10d7SGordon Ross 	obj = mdb_alloc(sizeof (struct drm_i915_gem_object), UM_SLEEP);
36547dc10d7SGordon Ross 	if (mdb_vread(obj, sizeof (struct drm_i915_gem_object),
36647dc10d7SGordon Ross 	    (uintptr_t)list.contain_ptr) == -1) {
36747dc10d7SGordon Ross 		mdb_warn("failed to read object infor");
36847dc10d7SGordon Ross 		ret = DCMD_ERR;
36947dc10d7SGordon Ross 		goto err;
37047dc10d7SGordon Ross 	}
37147dc10d7SGordon Ross 
37247dc10d7SGordon Ross 	mdb_printf("0x%lx ", list.contain_ptr);
37347dc10d7SGordon Ross 	i915_obj_info(obj);
37447dc10d7SGordon Ross 
37547dc10d7SGordon Ross err:
37647dc10d7SGordon Ross 	mdb_free(obj, sizeof (struct drm_i915_gem_object));
37747dc10d7SGordon Ross 	return (ret);
37847dc10d7SGordon Ross }
37947dc10d7SGordon Ross 
38047dc10d7SGordon Ross static int
obj_walk_list(uintptr_t addr,const char * str)38147dc10d7SGordon Ross obj_walk_list(uintptr_t addr, const char *str)
38247dc10d7SGordon Ross {
38347dc10d7SGordon Ross 	struct list_head *head;
38447dc10d7SGordon Ross 	int ret = DCMD_OK;
38547dc10d7SGordon Ross 
38647dc10d7SGordon Ross 	head = mdb_alloc(sizeof (struct list_head), UM_SLEEP);
38747dc10d7SGordon Ross 
38847dc10d7SGordon Ross 	if (mdb_vread(head, sizeof (struct list_head), addr) == -1) {
38947dc10d7SGordon Ross 		mdb_warn("failed to read active_list");
39047dc10d7SGordon Ross 		ret = DCMD_ERR;
39147dc10d7SGordon Ross 		goto err;
39247dc10d7SGordon Ross 	}
39347dc10d7SGordon Ross 	mdb_printf("Dump %s List\n", str);
39447dc10d7SGordon Ross 	mdb_printf("%s %20s %14s %9s %23s\n", "obj", "size", "gtt_off",
39547dc10d7SGordon Ross 	    "kaddr", "pfn_array");
39647dc10d7SGordon Ross 
39747dc10d7SGordon Ross 	if (mdb_pwalk_dcmd("head_list", "i915_obj_list_node",
39847dc10d7SGordon Ross 	    0, NULL, (uintptr_t)head->prev) == -1) {
39947dc10d7SGordon Ross 		mdb_warn("failed to walk head_list");
40047dc10d7SGordon Ross 		ret = DCMD_ERR;
40147dc10d7SGordon Ross 		goto err;
40247dc10d7SGordon Ross 	}
40347dc10d7SGordon Ross err:
40447dc10d7SGordon Ross 	mdb_free(head, sizeof (struct list_head));
40547dc10d7SGordon Ross 	return (ret);
40647dc10d7SGordon Ross }
40747dc10d7SGordon Ross 
40847dc10d7SGordon Ross void
i915_obj_list_help(void)40947dc10d7SGordon Ross i915_obj_list_help(void)
41047dc10d7SGordon Ross {
41147dc10d7SGordon Ross 	mdb_printf("Print object lists information\n"
41247dc10d7SGordon Ross 	    "Fields printed:\n"
41347dc10d7SGordon Ross 	    "       obj:\tpointer to drm_i915_gem_object structure\n"
41447dc10d7SGordon Ross 	    "       size:\tobject size\n"
41547dc10d7SGordon Ross 	    "       gtt_off:\tobject offset in GTT (graphics address)\n"
41647dc10d7SGordon Ross 	    "       kaddr:\tobject kernel virtual address\n"
41747dc10d7SGordon Ross 	    "       pfn_array:\tArrary which contains object's PFN\n"
41847dc10d7SGordon Ross 	    "Options:\n"
41947dc10d7SGordon Ross 	    "       -a flag:\tprint only active list with flag set\n"
42047dc10d7SGordon Ross 	    "       -i flag:\tprint only inactive list with flag set\n"
42147dc10d7SGordon Ross 	    "       -b flag:\tprint only bound list with flag set\n"
42247dc10d7SGordon Ross 	    "       -u flag:\tprint only unbound list with flag set\n"
42347dc10d7SGordon Ross 	    "\nWithout the option, print information about all objects in "
42447dc10d7SGordon Ross 	    "system.\n"
42547dc10d7SGordon Ross 	    "Please make sure mdb_track is enabled in i915 driver by "
42647dc10d7SGordon Ross 	    "mdb_track_enable,\n"
42747dc10d7SGordon Ross 	    "before dump all objects information.\n");
42847dc10d7SGordon Ross }
42947dc10d7SGordon Ross 
43047dc10d7SGordon Ross /* ARGSUSED */
43147dc10d7SGordon Ross static int
i915_obj_list(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)43247dc10d7SGordon Ross i915_obj_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
43347dc10d7SGordon Ross {
43447dc10d7SGordon Ross 	uint_t	list_flag = 0;
43547dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
43647dc10d7SGordon Ross 	int ret = DCMD_OK;
43747dc10d7SGordon Ross 
43847dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
43947dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx, just ignore\n",
44047dc10d7SGordon Ross 		    addr);
44147dc10d7SGordon Ross 	}
44247dc10d7SGordon Ross 
44347dc10d7SGordon Ross 	if (mdb_getopts(argc, argv,
44447dc10d7SGordon Ross 	    'a', MDB_OPT_SETBITS, ACTIVE_LIST, &list_flag,
44547dc10d7SGordon Ross 	    'i', MDB_OPT_SETBITS, INACTIVE_LIST, &list_flag,
44647dc10d7SGordon Ross 	    'b', MDB_OPT_SETBITS, BOUND_LIST, &list_flag,
44747dc10d7SGordon Ross 	    'u', MDB_OPT_SETBITS, UNBOUND_LIST, &list_flag, NULL) != argc) {
44847dc10d7SGordon Ross 		mdb_printf("\nUsage:\n"
44947dc10d7SGordon Ross 		    "-a dump active_list\n"
45047dc10d7SGordon Ross 		    "-i dump inactive_list\n"
45147dc10d7SGordon Ross 		    "-b dump bound_list\n"
45247dc10d7SGordon Ross 		    "-u dump unbound_list\n");
45347dc10d7SGordon Ross 		return (DCMD_USAGE);
45447dc10d7SGordon Ross 	}
45547dc10d7SGordon Ross 
45647dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
45747dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
45847dc10d7SGordon Ross 	if (ret != DCMD_OK) {
45947dc10d7SGordon Ross 		goto err;
46047dc10d7SGordon Ross 	}
46147dc10d7SGordon Ross 
46247dc10d7SGordon Ross 	mdb_printf("%u objects, 0x%lx bytes\n",
46347dc10d7SGordon Ross 	    dev_priv->mm.object_count, dev_priv->mm.object_memory);
46447dc10d7SGordon Ross 
46547dc10d7SGordon Ross 	if (list_flag == 0) {
46647dc10d7SGordon Ross 		int mdb_track = 0;
46747dc10d7SGordon Ross 		if (mdb_readvar(&mdb_track, "mdb_track_enable") == -1) {
46847dc10d7SGordon Ross 			mdb_warn("failed to read mdb_track");
46947dc10d7SGordon Ross 			mdb_track = 0;
47047dc10d7SGordon Ross 		}
47147dc10d7SGordon Ross 
47247dc10d7SGordon Ross 		if (mdb_track == 0) {
47347dc10d7SGordon Ross 			mdb_printf("mdb_track is not enabled. Please enable "
47447dc10d7SGordon Ross 			    "it by set drm:mdb_track_enable=1");
47547dc10d7SGordon Ross 			goto err;
47647dc10d7SGordon Ross 		}
47747dc10d7SGordon Ross 
47847dc10d7SGordon Ross 		/* dump whole gem objects list */
47947dc10d7SGordon Ross 		struct drm_device *drm_dev;
48047dc10d7SGordon Ross 		struct list_head *head;
48147dc10d7SGordon Ross 		drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
48247dc10d7SGordon Ross 		ret = get_drm_dev(drm_dev);
48347dc10d7SGordon Ross 		if (ret != DCMD_OK)
48447dc10d7SGordon Ross 			goto err2;
48547dc10d7SGordon Ross 
48647dc10d7SGordon Ross 		head = mdb_alloc(sizeof (struct list_head), UM_SLEEP);
48747dc10d7SGordon Ross 		if (mdb_vread(head, sizeof (struct list_head),
48847dc10d7SGordon Ross 		    (uintptr_t)drm_dev->gem_objects_list.next) == -1) {
48947dc10d7SGordon Ross 			mdb_warn("failed to read whole gem list");
49047dc10d7SGordon Ross 			ret = DCMD_ERR;
49147dc10d7SGordon Ross 			goto err1;
49247dc10d7SGordon Ross 		}
49347dc10d7SGordon Ross 
49447dc10d7SGordon Ross 		mdb_printf("Dump %s List\n", "Whole gem objects");
49547dc10d7SGordon Ross 		mdb_printf("%s %20s %14s %9s %23s\n", "obj", "size",
49647dc10d7SGordon Ross 		    "gtt_off", "kaddr", "pfn_array");
49747dc10d7SGordon Ross 
49847dc10d7SGordon Ross 		if (mdb_pwalk_dcmd("head_list", "i915_obj_list_node",
49947dc10d7SGordon Ross 		    0, NULL, (uintptr_t)head->prev) == -1) {
50047dc10d7SGordon Ross 			mdb_warn("failed to walk head_list");
50147dc10d7SGordon Ross 			ret = DCMD_ERR;
50247dc10d7SGordon Ross 			goto err;
50347dc10d7SGordon Ross 		}
50447dc10d7SGordon Ross err1:
50547dc10d7SGordon Ross 		mdb_free(head, sizeof (struct list_head));
50647dc10d7SGordon Ross err2:
50747dc10d7SGordon Ross 		mdb_free(drm_dev, sizeof (struct drm_device));
50847dc10d7SGordon Ross 		goto err;
50947dc10d7SGordon Ross 	}
51047dc10d7SGordon Ross 	if (list_flag & ACTIVE_LIST) {
51147dc10d7SGordon Ross 		size = count = mappable_size = mappable_count = 0;
51247dc10d7SGordon Ross 		ret = obj_walk_list((uintptr_t)dev_priv->mm.active_list.next,
51347dc10d7SGordon Ross 		    "Activate");
51447dc10d7SGordon Ross 		if (ret != DCMD_OK)
51547dc10d7SGordon Ross 			goto err;
51647dc10d7SGordon Ross 		mdb_printf("  %u [%u] active objects, 0x%lx [0x%lx] bytes\n",
51747dc10d7SGordon Ross 		    count, mappable_count, size, mappable_size);
51847dc10d7SGordon Ross 
51947dc10d7SGordon Ross 	}
52047dc10d7SGordon Ross 
52147dc10d7SGordon Ross 	if (list_flag & INACTIVE_LIST) {
52247dc10d7SGordon Ross 		size = count = mappable_size = mappable_count = 0;
52347dc10d7SGordon Ross 		ret = obj_walk_list((uintptr_t)dev_priv->mm.inactive_list.next,
52447dc10d7SGordon Ross 		    "Inactivate");
52547dc10d7SGordon Ross 		if (ret != DCMD_OK)
52647dc10d7SGordon Ross 			goto err;
52747dc10d7SGordon Ross 		mdb_printf("  %u [%u] inactive objects, 0x%lx [0x%lx] bytes\n",
52847dc10d7SGordon Ross 		    count, mappable_count, size, mappable_size);
52947dc10d7SGordon Ross 	}
53047dc10d7SGordon Ross 
53147dc10d7SGordon Ross 	if (list_flag & BOUND_LIST) {
53247dc10d7SGordon Ross 		size = count = mappable_size = mappable_count = 0;
53347dc10d7SGordon Ross 		ret = obj_walk_list((uintptr_t)dev_priv->mm.bound_list.next,
53447dc10d7SGordon Ross 		    "Bound");
53547dc10d7SGordon Ross 		if (ret != DCMD_OK)
53647dc10d7SGordon Ross 			goto err;
53747dc10d7SGordon Ross 		mdb_printf("%u [%u] objects, 0x%lx [0x%lx] bytes in gtt\n",
53847dc10d7SGordon Ross 		    count, mappable_count, size, mappable_size);
53947dc10d7SGordon Ross 
54047dc10d7SGordon Ross 	}
54147dc10d7SGordon Ross 
54247dc10d7SGordon Ross 	if (list_flag & UNBOUND_LIST) {
54347dc10d7SGordon Ross 		size = count = purgeable_size = purgeable_count = 0;
54447dc10d7SGordon Ross 		ret = obj_walk_list((uintptr_t)dev_priv->mm.unbound_list.next,
54547dc10d7SGordon Ross 		    "Unbound");
54647dc10d7SGordon Ross 		if (ret != DCMD_OK)
54747dc10d7SGordon Ross 			goto err;
54847dc10d7SGordon Ross 		mdb_printf("%u unbound objects, 0x%lx bytes\n", count, size);
54947dc10d7SGordon Ross 	}
55047dc10d7SGordon Ross 
55147dc10d7SGordon Ross err:
55247dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
55347dc10d7SGordon Ross 	return (ret);
55447dc10d7SGordon Ross }
55547dc10d7SGordon Ross 
55647dc10d7SGordon Ross void
i915_ringbuffer_info_help(void)55747dc10d7SGordon Ross i915_ringbuffer_info_help(void)
55847dc10d7SGordon Ross {
55947dc10d7SGordon Ross 	mdb_printf("Print ring object information\n"
56047dc10d7SGordon Ross 	"Fields printed:\n"
56147dc10d7SGordon Ross 	"       mmio_base:\tMMIO base address\n"
56247dc10d7SGordon Ross 	"       obj:\tpointer to ring object's drm_i915_gem_object structure\n"
56347dc10d7SGordon Ross 	"Options:\n"
56447dc10d7SGordon Ross 	"       -l flag:\tprint only BLT ring information with flag set\n"
56547dc10d7SGordon Ross 	"       -r flag:\tprint only RENDER ring information with flag set\n"
56647dc10d7SGordon Ross 	"       -s flag:\tprint only BSD ring information with flag set\n"
56747dc10d7SGordon Ross 	"Without the option given, print information about all rings.\n");
56847dc10d7SGordon Ross }
56947dc10d7SGordon Ross 
57047dc10d7SGordon Ross /* ARGSUSED */
57147dc10d7SGordon Ross static int
i915_ringbuffer_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)57247dc10d7SGordon Ross i915_ringbuffer_info(uintptr_t addr, uint_t flags, int argc,
57347dc10d7SGordon Ross     const mdb_arg_t *argv)
57447dc10d7SGordon Ross {
57547dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
57647dc10d7SGordon Ross 	uint_t  ring_flag = 0;
57747dc10d7SGordon Ross 	int ret = DCMD_OK;
57847dc10d7SGordon Ross 
57947dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
58047dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx, just ignore\n",
58147dc10d7SGordon Ross 		    addr);
58247dc10d7SGordon Ross 	}
58347dc10d7SGordon Ross 
58447dc10d7SGordon Ross 	if (mdb_getopts(argc, argv,
58547dc10d7SGordon Ross 	    'l', MDB_OPT_SETBITS, BLT_RING, &ring_flag,
58647dc10d7SGordon Ross 	    'r', MDB_OPT_SETBITS, RENDER_RING, &ring_flag,
58747dc10d7SGordon Ross 	    's', MDB_OPT_SETBITS, BSD_RING, &ring_flag, NULL) != argc) {
58847dc10d7SGordon Ross 		mdb_printf("\nUsage:\n"
58947dc10d7SGordon Ross 		    "-l blt ring information\n"
59047dc10d7SGordon Ross 		    "-r render ring information\n"
59147dc10d7SGordon Ross 		    "-s bsd ring information\n");
59247dc10d7SGordon Ross 		return (DCMD_USAGE);
59347dc10d7SGordon Ross 	}
59447dc10d7SGordon Ross 
59547dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
59647dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
59747dc10d7SGordon Ross 		if (ret != DCMD_OK) {
59847dc10d7SGordon Ross 		goto err;
59947dc10d7SGordon Ross 	}
60047dc10d7SGordon Ross 
60147dc10d7SGordon Ross 	if (ring_flag == 0)
60247dc10d7SGordon Ross 		ring_flag = 0xff;
60347dc10d7SGordon Ross 
60447dc10d7SGordon Ross 	if (ring_flag & RENDER_RING) {
60547dc10d7SGordon Ross 		mdb_printf("Render ring mmio_base 0x%lx obj 0x%lx\n",
60647dc10d7SGordon Ross 		    dev_priv->ring[0].mmio_base,
60747dc10d7SGordon Ross 		    dev_priv->ring[0].obj);
60847dc10d7SGordon Ross 	}
60947dc10d7SGordon Ross 
61047dc10d7SGordon Ross 	if (ring_flag & BLT_RING) {
61147dc10d7SGordon Ross 		mdb_printf("BLT ring mmio_base 0x%lx obj 0x%lx\n",
61247dc10d7SGordon Ross 		    dev_priv->ring[2].mmio_base,
61347dc10d7SGordon Ross 		    dev_priv->ring[2].obj);
61447dc10d7SGordon Ross 	}
61547dc10d7SGordon Ross 
61647dc10d7SGordon Ross 	if (ring_flag & BSD_RING) {
61747dc10d7SGordon Ross 		mdb_printf("BSD ring mmio_base 0x%lx obj 0x%lx\n",
61847dc10d7SGordon Ross 		    dev_priv->ring[1].mmio_base,
61947dc10d7SGordon Ross 		    dev_priv->ring[1].obj);
62047dc10d7SGordon Ross 	}
62147dc10d7SGordon Ross 
62247dc10d7SGordon Ross err:
62347dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
62447dc10d7SGordon Ross 	return (ret);
62547dc10d7SGordon Ross }
62647dc10d7SGordon Ross 
62747dc10d7SGordon Ross void
i915_gtt_dump_help(void)62847dc10d7SGordon Ross i915_gtt_dump_help(void)
62947dc10d7SGordon Ross {
63047dc10d7SGordon Ross 	mdb_printf("Print the address of gtt_dump\n"
63147dc10d7SGordon Ross 	    "\ngtt_dump is a snapshot of whole GTT table when GPU hang "
63247dc10d7SGordon Ross 	    "happened.\n"
63347dc10d7SGordon Ross 	    "Please make sure gpu_dump is enabled in i915 driver before "
63447dc10d7SGordon Ross 	    "using it.\n"
63547dc10d7SGordon Ross 	    "\nSee also: \"::help i915_error_reg_dump\"\n");
63647dc10d7SGordon Ross }
63747dc10d7SGordon Ross 
63847dc10d7SGordon Ross /* ARGSUSED */
63947dc10d7SGordon Ross static int
i915_gtt_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)64047dc10d7SGordon Ross i915_gtt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
64147dc10d7SGordon Ross {
64247dc10d7SGordon Ross 	struct drm_device *drm_dev;
64347dc10d7SGordon Ross 	int ret = DCMD_OK;
64447dc10d7SGordon Ross 
64547dc10d7SGordon Ross 	drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
64647dc10d7SGordon Ross 	ret = get_drm_dev(drm_dev);
64747dc10d7SGordon Ross 	if (ret != DCMD_OK) {
64847dc10d7SGordon Ross 		goto err;
64947dc10d7SGordon Ross 	}
65047dc10d7SGordon Ross 
65147dc10d7SGordon Ross 	if (drm_dev->gtt_dump != 0)
65247dc10d7SGordon Ross 		mdb_printf("gtt_dump address 0x%lx\n", drm_dev->gtt_dump);
65347dc10d7SGordon Ross 	else
65447dc10d7SGordon Ross 		mdb_printf("There is no gtt_dump");
65547dc10d7SGordon Ross 
65647dc10d7SGordon Ross err:
65747dc10d7SGordon Ross 	mdb_free(drm_dev, sizeof (struct drm_device));
65847dc10d7SGordon Ross 	return (ret);
65947dc10d7SGordon Ross }
66047dc10d7SGordon Ross 
66147dc10d7SGordon Ross static uint32_t
i915_read(struct drm_i915_private * dev_priv,uintptr_t addr,uint32_t * val)66247dc10d7SGordon Ross i915_read(struct drm_i915_private *dev_priv, uintptr_t addr, uint32_t *val)
66347dc10d7SGordon Ross {
66447dc10d7SGordon Ross 	struct drm_local_map regs;
66547dc10d7SGordon Ross 	int ret = DCMD_OK;
66647dc10d7SGordon Ross 
66747dc10d7SGordon Ross 	if (mdb_vread(&regs, sizeof (struct drm_local_map),
66847dc10d7SGordon Ross 	    (intptr_t)dev_priv->regs) == -1) {
66947dc10d7SGordon Ross 		mdb_warn("Failed to read dev_priv->regs\n");
67047dc10d7SGordon Ross 		ret = DCMD_ERR;
67147dc10d7SGordon Ross 		return (ret);
67247dc10d7SGordon Ross 	}
67347dc10d7SGordon Ross 
67447dc10d7SGordon Ross 	if (mdb_pread(val, sizeof (uint32_t),
67547dc10d7SGordon Ross 	    (intptr_t)regs.offset + addr) == -1) {
67647dc10d7SGordon Ross 		mdb_warn("Failed to read register 0x%x\n", addr);
67747dc10d7SGordon Ross 		ret = DCMD_ERR;
67847dc10d7SGordon Ross 		return (ret);
67947dc10d7SGordon Ross 	}
68047dc10d7SGordon Ross 
68147dc10d7SGordon Ross 	return (ret);
68247dc10d7SGordon Ross 
68347dc10d7SGordon Ross }
68447dc10d7SGordon Ross 
68547dc10d7SGordon Ross void
i915_register_read_help(void)68647dc10d7SGordon Ross i915_register_read_help(void)
68747dc10d7SGordon Ross {
68847dc10d7SGordon Ross 	mdb_printf("Print register value for a given register offset\n");
68947dc10d7SGordon Ross }
69047dc10d7SGordon Ross 
69147dc10d7SGordon Ross /* ARGSUSED */
69247dc10d7SGordon Ross static int
i915_register_read(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)69347dc10d7SGordon Ross i915_register_read(uintptr_t addr, uint_t flags, int argc,
69447dc10d7SGordon Ross     const mdb_arg_t *argv)
69547dc10d7SGordon Ross {
69647dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
69747dc10d7SGordon Ross 	int ret = DCMD_OK;
69847dc10d7SGordon Ross 	uint32_t val;
69947dc10d7SGordon Ross 
70047dc10d7SGordon Ross 	if (!(flags & DCMD_ADDRSPEC)) {
70147dc10d7SGordon Ross 		return (DCMD_USAGE);
70247dc10d7SGordon Ross 	}
70347dc10d7SGordon Ross 
70447dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
70547dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
70647dc10d7SGordon Ross 	if (ret != DCMD_OK) {
70747dc10d7SGordon Ross 		goto err;
70847dc10d7SGordon Ross 	}
70947dc10d7SGordon Ross 	ret = i915_read(dev_priv, addr, &val);
71047dc10d7SGordon Ross 	if (ret == DCMD_ERR) {
71147dc10d7SGordon Ross 		goto err;
71247dc10d7SGordon Ross 	}
71347dc10d7SGordon Ross 
71447dc10d7SGordon Ross 	mdb_printf("Register [0x%x]: 0x%x\n", addr, val);
71547dc10d7SGordon Ross err:
71647dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
71747dc10d7SGordon Ross 	return (ret);
71847dc10d7SGordon Ross }
71947dc10d7SGordon Ross 
72047dc10d7SGordon Ross void
i915_error_reg_dump_help(void)72147dc10d7SGordon Ross i915_error_reg_dump_help(void)
72247dc10d7SGordon Ross {
72347dc10d7SGordon Ross 	mdb_printf("Print debug register information\n"
72447dc10d7SGordon Ross 	"Registers printed:\n"
72547dc10d7SGordon Ross 	"       PGTBL_ER:\tPage Table Errors Register\n"
72647dc10d7SGordon Ross 	"       INSTPM:\tCommand Parser Mode Register\n"
72747dc10d7SGordon Ross 	"       EIR:\tError Identity Register\n"
72847dc10d7SGordon Ross 	"       EHR:\tError Header Register\n"
72947dc10d7SGordon Ross 	"       INSTDONE:\tInstruction Stream Interface Done Register\n"
73047dc10d7SGordon Ross 	"       INSTDONE1:\tInstruction Stream Interface Done 1\n"
73147dc10d7SGordon Ross 	"       INSTPS:\tInstruction Parser State Register\n"
73247dc10d7SGordon Ross 	"       ACTHD:\tActive Head Pointer Register\n"
73347dc10d7SGordon Ross 	"       DMA_FADD_P:\tPrimary DMA Engine Fetch Address Register\n"
73447dc10d7SGordon Ross 	"\ngtt_dump is a snapshot of whole GTT table when GPU hang happened.\n"
73547dc10d7SGordon Ross 	"\nSee also: \"::help i915_gtt_dump\"\n");
73647dc10d7SGordon Ross }
73747dc10d7SGordon Ross 
73847dc10d7SGordon Ross /* ARGSUSED */
73947dc10d7SGordon Ross static int
i915_error_reg_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)74047dc10d7SGordon Ross i915_error_reg_dump(uintptr_t addr, uint_t flags, int argc,
74147dc10d7SGordon Ross     const mdb_arg_t *argv)
74247dc10d7SGordon Ross {
74347dc10d7SGordon Ross 	struct drm_device *dev;
74447dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
74547dc10d7SGordon Ross 	int ret = DCMD_OK;
74647dc10d7SGordon Ross 	uint32_t val;
74747dc10d7SGordon Ross 
74847dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
74947dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
75047dc10d7SGordon Ross 		return (DCMD_OK);
75147dc10d7SGordon Ross 	}
75247dc10d7SGordon Ross 
75347dc10d7SGordon Ross 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
75447dc10d7SGordon Ross 	ret = get_drm_dev(dev);
75547dc10d7SGordon Ross 	if (ret == DCMD_ERR)
75647dc10d7SGordon Ross 		goto err1;
75747dc10d7SGordon Ross 
75847dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
75947dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
76047dc10d7SGordon Ross 	if (ret != DCMD_OK) {
76147dc10d7SGordon Ross 		goto err2;
76247dc10d7SGordon Ross 	}
76347dc10d7SGordon Ross 
76447dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)PGTBL_ER, &val);
76547dc10d7SGordon Ross 	if (ret == DCMD_OK)
76647dc10d7SGordon Ross 		mdb_printf("PGTBL_ER: 0x%lx\n", val);
76747dc10d7SGordon Ross 
76847dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)INSTPM, &val);
76947dc10d7SGordon Ross 	if (ret == DCMD_OK)
77047dc10d7SGordon Ross 		mdb_printf("INSTPM: 0x%lx\n", val);
77147dc10d7SGordon Ross 
77247dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)EIR, &val);
77347dc10d7SGordon Ross 	if (ret == DCMD_OK)
77447dc10d7SGordon Ross 		mdb_printf("EIR: 0x%lx\n", val);
77547dc10d7SGordon Ross 
77647dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)ERROR_GEN6, &val);
77747dc10d7SGordon Ross 	if (ret == DCMD_OK)
77847dc10d7SGordon Ross 		mdb_printf("ERROR_GEN6: 0x%lx\n", val);
77947dc10d7SGordon Ross 
780*e1cb3391SAlexander Pyhalov 	mdb_printf("\nBlitter command stream:\n");
78147dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)0x22064, &val);
78247dc10d7SGordon Ross 	if (ret == DCMD_OK)
78347dc10d7SGordon Ross 		mdb_printf("  BLT EIR: 0x%08x\n", val);
78447dc10d7SGordon Ross 
78547dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)0x22068, &val);
78647dc10d7SGordon Ross 	if (ret == DCMD_OK)
78747dc10d7SGordon Ross 		mdb_printf("  BLT EHR: 0x%08x\n", val);
78847dc10d7SGordon Ross 
78947dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)0x2206C, &val);
79047dc10d7SGordon Ross 	if (ret == DCMD_OK)
79147dc10d7SGordon Ross 		mdb_printf("  INSTDONE: 0x%08x\n", val);
79247dc10d7SGordon Ross 
79347dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)0x22074, &val);
79447dc10d7SGordon Ross 	if (ret == DCMD_OK)
79547dc10d7SGordon Ross 		mdb_printf("  ACTHD: 0x%08x\n", val);
79647dc10d7SGordon Ross 
79747dc10d7SGordon Ross 
79847dc10d7SGordon Ross 	mdb_printf("\nRender command stream:\n");
79947dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)IPEIR_I965, &val);
80047dc10d7SGordon Ross 	if (ret == DCMD_OK)
80147dc10d7SGordon Ross 		mdb_printf("  RENDER EIR: 0x%08x\n", val);
80247dc10d7SGordon Ross 
80347dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)IPEHR_I965, &val);
80447dc10d7SGordon Ross 	if (ret == DCMD_OK)
80547dc10d7SGordon Ross 		mdb_printf("  RENDER EHR: 0x%08x\n", val);
80647dc10d7SGordon Ross 
80747dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)INSTDONE_I965, &val);
80847dc10d7SGordon Ross 	if (ret == DCMD_OK)
80947dc10d7SGordon Ross 		mdb_printf("  INSTDONE: 0x%08x\n", val);
81047dc10d7SGordon Ross 
81147dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)INSTPS, &val);
81247dc10d7SGordon Ross 	if (ret == DCMD_OK)
81347dc10d7SGordon Ross 		mdb_printf("  INSTPS: 0x%08x\n", val);
81447dc10d7SGordon Ross 
81547dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)INSTDONE1, &val);
81647dc10d7SGordon Ross 	if (ret == DCMD_OK)
81747dc10d7SGordon Ross 		mdb_printf("  INSTDONE1: 0x%08x\n", val);
81847dc10d7SGordon Ross 
81947dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)ACTHD_I965, &val);
82047dc10d7SGordon Ross 	if (ret == DCMD_OK)
82147dc10d7SGordon Ross 		mdb_printf("  ACTHD: 0x%08x\n", val);
82247dc10d7SGordon Ross 
82347dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)0x2078, &val);
82447dc10d7SGordon Ross 	if (ret == DCMD_OK)
82547dc10d7SGordon Ross 		mdb_printf("  DMA_FADD_P: 0x%08x\n", val);
82647dc10d7SGordon Ross 
82747dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)0x04094, &val);
82847dc10d7SGordon Ross 	if (ret == DCMD_OK)
82947dc10d7SGordon Ross 		mdb_printf("\nGraphics Engine Fault 0x%lx\n", val);
83047dc10d7SGordon Ross 
83147dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)0x04194, &val);
83247dc10d7SGordon Ross 	if (ret == DCMD_OK)
83347dc10d7SGordon Ross 		mdb_printf("Media Engine Fault 0x%lx\n", val);
83447dc10d7SGordon Ross 
83547dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)0x04294, &val);
83647dc10d7SGordon Ross 	if (ret == DCMD_OK)
83747dc10d7SGordon Ross 		mdb_printf("Blitter  Engine Fault 0x%lx\n", val);
83847dc10d7SGordon Ross 
83947dc10d7SGordon Ross 	if (dev->gtt_dump != NULL)
84047dc10d7SGordon Ross 		mdb_printf("gtt dump to %p\n", dev->gtt_dump);
84147dc10d7SGordon Ross 	else
84247dc10d7SGordon Ross 		mdb_printf("no gtt dump\n");
84347dc10d7SGordon Ross err2:
84447dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
84547dc10d7SGordon Ross err1:
84647dc10d7SGordon Ross 	mdb_free(dev, sizeof (struct drm_device));
84747dc10d7SGordon Ross 
84847dc10d7SGordon Ross 	return (ret);
84947dc10d7SGordon Ross 
85047dc10d7SGordon Ross }
85147dc10d7SGordon Ross 
85247dc10d7SGordon Ross void
i915_obj_history_help(void)85347dc10d7SGordon Ross i915_obj_history_help(void)
85447dc10d7SGordon Ross {
85547dc10d7SGordon Ross 	mdb_printf("Print object history information for a given "
85647dc10d7SGordon Ross 	    "drm_i915_gem_object pointer\n"
85747dc10d7SGordon Ross 	    "Fields printed:\n"
85847dc10d7SGordon Ross 	    "       event:\tOperation name\n"
85947dc10d7SGordon Ross 	    "       cur_seq:\tCurrent system SeqNO\n"
86047dc10d7SGordon Ross 	    "       last_seq:\tLast SeqNO has been processed\n"
86147dc10d7SGordon Ross 	    "       ring addr:\tPoint to intel_ring_buffer structure\n"
86247dc10d7SGordon Ross 	    "\nNOTE: Please make sure mdb_track is enabled in i915 driver "
86347dc10d7SGordon Ross 	    "by setting mdb_track_enable\n");
86447dc10d7SGordon Ross }
86547dc10d7SGordon Ross 
86647dc10d7SGordon Ross /* ARGSUSED */
86747dc10d7SGordon Ross static int
i915_obj_history(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)86847dc10d7SGordon Ross i915_obj_history(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
86947dc10d7SGordon Ross {
87047dc10d7SGordon Ross 	struct drm_gem_object obj;
87147dc10d7SGordon Ross 	struct list_head node;
87247dc10d7SGordon Ross 	uintptr_t temp;
87347dc10d7SGordon Ross 	struct drm_history_list history_node;
87447dc10d7SGordon Ross 	int ret = DCMD_OK;
87547dc10d7SGordon Ross 	int condition = 1;
87647dc10d7SGordon Ross 	int mdb_track = 0;
87747dc10d7SGordon Ross 
87847dc10d7SGordon Ross 	if (!(flags & DCMD_ADDRSPEC)) {
87947dc10d7SGordon Ross 		return (DCMD_USAGE);
88047dc10d7SGordon Ross 	}
88147dc10d7SGordon Ross 
88247dc10d7SGordon Ross 	if (mdb_vread(&obj, sizeof (struct drm_gem_object), addr) == -1) {
88347dc10d7SGordon Ross 		mdb_warn("failed to read gem object infor");
88447dc10d7SGordon Ross 		ret = DCMD_ERR;
88547dc10d7SGordon Ross 		goto err;
88647dc10d7SGordon Ross 	}
88747dc10d7SGordon Ross 
88847dc10d7SGordon Ross 	if (mdb_readvar(&mdb_track, "mdb_track_enable") == -1) {
88947dc10d7SGordon Ross 		mdb_warn("failed to read mdb_track");
89047dc10d7SGordon Ross 		mdb_track = 0;
89147dc10d7SGordon Ross 	}
89247dc10d7SGordon Ross 
89347dc10d7SGordon Ross 	if (mdb_track == 0) {
89447dc10d7SGordon Ross 		mdb_printf("mdb_track is not enabled. Please enable it "
89547dc10d7SGordon Ross 		    "by set drm:mdb_track_enable=1");
89647dc10d7SGordon Ross 		goto err;
89747dc10d7SGordon Ross 	}
89847dc10d7SGordon Ross 
89947dc10d7SGordon Ross 	mdb_printf("Dump obj history\n");
90047dc10d7SGordon Ross 	mdb_printf("%s %20s %10s %10s\n", "event", "cur_seq", "last_seq",
90147dc10d7SGordon Ross 	    "ring addr");
90247dc10d7SGordon Ross 	temp = (uintptr_t)obj.his_list.next;
90347dc10d7SGordon Ross 	while (condition) {
90447dc10d7SGordon Ross 		if (mdb_vread(&node, sizeof (struct list_head), temp) == -1) {
90547dc10d7SGordon Ross 			mdb_warn("failed to read his_list node");
90647dc10d7SGordon Ross 			ret = DCMD_ERR;
90747dc10d7SGordon Ross 			goto err;
90847dc10d7SGordon Ross 		}
90947dc10d7SGordon Ross 
91047dc10d7SGordon Ross 		if (node.contain_ptr == NULL)
91147dc10d7SGordon Ross 			break;
91247dc10d7SGordon Ross 
91347dc10d7SGordon Ross 		if (mdb_vread(&history_node, sizeof (struct drm_history_list),
91447dc10d7SGordon Ross 		    (uintptr_t)node.contain_ptr) == -1) {
91547dc10d7SGordon Ross 			mdb_warn("failed to read history node");
91647dc10d7SGordon Ross 			ret = DCMD_ERR;
91747dc10d7SGordon Ross 			goto err;
91847dc10d7SGordon Ross 		}
91947dc10d7SGordon Ross 
92047dc10d7SGordon Ross 		mdb_printf("%s %-8d %-8d 0x%lx\n", history_node.info,
92147dc10d7SGordon Ross 		    history_node.cur_seq, history_node.last_seq,
92247dc10d7SGordon Ross 		    history_node.ring_ptr);
92347dc10d7SGordon Ross 
92447dc10d7SGordon Ross 		temp = (uintptr_t)node.next;
92547dc10d7SGordon Ross 	}
92647dc10d7SGordon Ross 
92747dc10d7SGordon Ross err:
92847dc10d7SGordon Ross 	return (ret);
92947dc10d7SGordon Ross }
93047dc10d7SGordon Ross 
93147dc10d7SGordon Ross void
i915_batch_history_help(void)93247dc10d7SGordon Ross i915_batch_history_help(void)
93347dc10d7SGordon Ross {
93447dc10d7SGordon Ross 	mdb_printf("Print batchbuffer information\n"
93547dc10d7SGordon Ross 	    "\nAll batchbuffers' information is printed one by one "
93647dc10d7SGordon Ross 	    "from the latest one to the oldest one.\n"
93747dc10d7SGordon Ross 	    "The information includes objects number, assigned SeqNO. "
93847dc10d7SGordon Ross 	    "and objects list.\n"
93947dc10d7SGordon Ross 	    "\nNOTE: Please make sure mdb_track is enabled in i915 "
94047dc10d7SGordon Ross 	    "driver by setting mdb_track_enable\n");
94147dc10d7SGordon Ross 
94247dc10d7SGordon Ross }
94347dc10d7SGordon Ross 
94447dc10d7SGordon Ross /* ARGSUSED */
94547dc10d7SGordon Ross static int
i915_batch_history(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)94647dc10d7SGordon Ross i915_batch_history(uintptr_t addr, uint_t flags, int argc,
94747dc10d7SGordon Ross     const mdb_arg_t *argv)
94847dc10d7SGordon Ross {
94947dc10d7SGordon Ross 	struct list_head node;
95047dc10d7SGordon Ross 	uintptr_t temp;
95147dc10d7SGordon Ross 	struct batch_info_list batch_node;
95247dc10d7SGordon Ross 	caddr_t *obj_list;
95347dc10d7SGordon Ross 	int ret, i;
95447dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
95547dc10d7SGordon Ross 	int condition = 1;
95647dc10d7SGordon Ross 	int mdb_track = 0;
95747dc10d7SGordon Ross 
95847dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
95947dc10d7SGordon Ross 
96047dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
96147dc10d7SGordon Ross 	if (ret != DCMD_OK) {
96247dc10d7SGordon Ross 		mdb_warn("failed to read history node");
96347dc10d7SGordon Ross 		goto err;
96447dc10d7SGordon Ross 	}
96547dc10d7SGordon Ross 
96647dc10d7SGordon Ross 	if (mdb_readvar(&mdb_track, "mdb_track_enable") == -1) {
96747dc10d7SGordon Ross 		mdb_warn("failed to read mdb_track");
96847dc10d7SGordon Ross 		mdb_track = 0;
96947dc10d7SGordon Ross 	}
97047dc10d7SGordon Ross 	if (mdb_track == 0) {
97147dc10d7SGordon Ross 		mdb_printf("mdb_track is not enabled. Please enable it by "
97247dc10d7SGordon Ross 		    "set drm:mdb_track_enable=1");
97347dc10d7SGordon Ross 		goto err;
97447dc10d7SGordon Ross 	}
97547dc10d7SGordon Ross 
97647dc10d7SGordon Ross 	mdb_printf("Dump batchbuffer history\n");
97747dc10d7SGordon Ross 	temp = (uintptr_t)dev_priv->batch_list.next;
97847dc10d7SGordon Ross 	while (condition) {
97947dc10d7SGordon Ross 
98047dc10d7SGordon Ross 		if (mdb_vread(&node, sizeof (struct list_head), temp) == -1) {
98147dc10d7SGordon Ross 			mdb_warn("failed to read his_list node");
98247dc10d7SGordon Ross 			ret = DCMD_ERR;
98347dc10d7SGordon Ross 			goto err;
98447dc10d7SGordon Ross 		}
98547dc10d7SGordon Ross 
98647dc10d7SGordon Ross 		if (node.contain_ptr == NULL)
98747dc10d7SGordon Ross 			break;
98847dc10d7SGordon Ross 
98947dc10d7SGordon Ross 		if (mdb_vread(&batch_node, sizeof (struct batch_info_list),
99047dc10d7SGordon Ross 		    (uintptr_t)node.contain_ptr) == -1) {
99147dc10d7SGordon Ross 			mdb_warn("failed to read batch node");
99247dc10d7SGordon Ross 			ret = DCMD_ERR;
99347dc10d7SGordon Ross 			goto err;
99447dc10d7SGordon Ross 		}
99547dc10d7SGordon Ross 
99647dc10d7SGordon Ross 		mdb_printf("batch buffer includes %d objects, seqno 0x%x\n",
99747dc10d7SGordon Ross 		    batch_node.num, batch_node.seqno);
99847dc10d7SGordon Ross 
99947dc10d7SGordon Ross 		obj_list = mdb_alloc(batch_node.num * sizeof (caddr_t),
100047dc10d7SGordon Ross 		    UM_SLEEP);
100147dc10d7SGordon Ross 		if (mdb_vread(obj_list, batch_node.num * sizeof (caddr_t),
100247dc10d7SGordon Ross 		    (uintptr_t)batch_node.obj_list) == -1) {
100347dc10d7SGordon Ross 			mdb_warn("failed to read batch object list");
100447dc10d7SGordon Ross 			ret = DCMD_ERR;
100547dc10d7SGordon Ross 			goto err;
100647dc10d7SGordon Ross 		}
100747dc10d7SGordon Ross 
100847dc10d7SGordon Ross 
100947dc10d7SGordon Ross 		for (i = 0; i < batch_node.num; i++) {
101047dc10d7SGordon Ross 			mdb_printf("obj: 0x%lx\n", obj_list[i]);
101147dc10d7SGordon Ross 		}
101247dc10d7SGordon Ross 
101347dc10d7SGordon Ross 		mdb_free(obj_list, batch_node.num * sizeof (caddr_t));
101447dc10d7SGordon Ross 
101547dc10d7SGordon Ross 		temp = (uintptr_t)node.next;
101647dc10d7SGordon Ross 	}
101747dc10d7SGordon Ross 
101847dc10d7SGordon Ross err:
101947dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
102047dc10d7SGordon Ross 	return (ret);
102147dc10d7SGordon Ross }
102247dc10d7SGordon Ross 
yesno(int v)102347dc10d7SGordon Ross static const char *yesno(int v)
102447dc10d7SGordon Ross {
102547dc10d7SGordon Ross 	return (v ? "yes" : "no");
102647dc10d7SGordon Ross }
102747dc10d7SGordon Ross 
102847dc10d7SGordon Ross void
i915_capabilities_help(void)102947dc10d7SGordon Ross i915_capabilities_help(void)
103047dc10d7SGordon Ross {
103147dc10d7SGordon Ross 	mdb_printf("Print capability information for Intel graphics card\n"
103247dc10d7SGordon Ross 	    "Fields printed:\n"
103347dc10d7SGordon Ross 	    "	is_mobile:\tMobile Platform\n"
103447dc10d7SGordon Ross 	    "       is_i85x:\tIntel I85x series graphics card\n"
103547dc10d7SGordon Ross 	    "       is_i915g:\tIntel I915g series graphics card\n"
103647dc10d7SGordon Ross 	    "       is_i945gm:\tIntel I945gm series graphics card\n"
103747dc10d7SGordon Ross 	    "       is_g33:\tIntel G33 series graphics card\n"
103847dc10d7SGordon Ross 	    "       need_gfx_hws:\tNeed setup graphics hardware status page\n"
103947dc10d7SGordon Ross 	    "       is_g4x:\tIntel G4x series graphics card\n"
104047dc10d7SGordon Ross 	    "       is_pineview:\tIntel Pineview series graphics card\n"
104147dc10d7SGordon Ross 	    "       is_broadwater:\tIntel Broadwater series graphics card\n"
104247dc10d7SGordon Ross 	    "       is_crestline:\tIntel Crestline series graphics card\n"
104347dc10d7SGordon Ross 	    "       is_ivybridge:\tIntel Ivybridge series graphics card\n"
104447dc10d7SGordon Ross 	    "       is_valleyview:\tIntel Valleyview series graphics card\n"
104547dc10d7SGordon Ross 	    "       has_force_wake:\tHas force awake\n"
104647dc10d7SGordon Ross 	    "       is_haswell:\tIntel Haswell series graphics card\n"
104747dc10d7SGordon Ross 	    "       has_fbc:\tHas Framebuffer compression\n"
104847dc10d7SGordon Ross 	    "       has_pipe_cxsr:\tHas CxSR\n"
104947dc10d7SGordon Ross 	    "       has_hotplug:\tHas output hotplug\n"
105047dc10d7SGordon Ross 	    "       cursor_needs_physical:\tHas physical cursor object\n"
105147dc10d7SGordon Ross 	    "       has_overlay:\tHas Overlay\n"
105247dc10d7SGordon Ross 	    "       overlay_needs_physical:\tHas physical overlay object\n"
105347dc10d7SGordon Ross 	    "       supports_tv:\tSupport TV output\n"
105447dc10d7SGordon Ross 	    "       has_bsd_ring:\tHas BSD ring\n"
105547dc10d7SGordon Ross 	    "       has_blt_ring:\tHas BLT ring\n"
105647dc10d7SGordon Ross 	    "       has_llc:\tHas last level cache\n");
105747dc10d7SGordon Ross }
105847dc10d7SGordon Ross 
105947dc10d7SGordon Ross /* ARGSUSED */
106047dc10d7SGordon Ross static int
i915_capabilities(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)106147dc10d7SGordon Ross i915_capabilities(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
106247dc10d7SGordon Ross {
106347dc10d7SGordon Ross 	int ret;
106447dc10d7SGordon Ross 	struct drm_device *drm_dev;
106547dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
106647dc10d7SGordon Ross 	struct intel_device_info info;
106747dc10d7SGordon Ross 
106847dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
106947dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
107047dc10d7SGordon Ross 		return (DCMD_OK);
107147dc10d7SGordon Ross 	}
107247dc10d7SGordon Ross 
107347dc10d7SGordon Ross 	drm_dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
107447dc10d7SGordon Ross 
107547dc10d7SGordon Ross 	ret = get_drm_dev(drm_dev);
107647dc10d7SGordon Ross 	if (ret == DCMD_ERR)
107747dc10d7SGordon Ross 		goto err1;
107847dc10d7SGordon Ross 
107947dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
108047dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
108147dc10d7SGordon Ross 	if (ret != DCMD_OK) {
108247dc10d7SGordon Ross 		goto err2;
108347dc10d7SGordon Ross 	}
108447dc10d7SGordon Ross 
108547dc10d7SGordon Ross 	if (mdb_vread(&info, sizeof (struct intel_device_info),
108647dc10d7SGordon Ross 	    (uintptr_t)dev_priv->info) == -1) {
108747dc10d7SGordon Ross 		mdb_warn("failed to read i915 chip info");
108847dc10d7SGordon Ross 		ret = DCMD_ERR;
108947dc10d7SGordon Ross 		goto err2;
109047dc10d7SGordon Ross 	}
109147dc10d7SGordon Ross 
109247dc10d7SGordon Ross 	mdb_printf("gen: %d\n", info.gen);
109347dc10d7SGordon Ross 	mdb_printf("pch: %d\n", dev_priv->pch_type);
109447dc10d7SGordon Ross 
109547dc10d7SGordon Ross 
109647dc10d7SGordon Ross /* BEGIN CSTYLED */
109747dc10d7SGordon Ross #define	SEP_SEMICOLON	;
109847dc10d7SGordon Ross #define	DEFINE_FLAG(x)	mdb_printf(#x ": %s\n", yesno(info.x))
109947dc10d7SGordon Ross 	DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
110047dc10d7SGordon Ross #undef	DEFINE_FLAG
110147dc10d7SGordon Ross #undef	SEP_SEMICOLON
110247dc10d7SGordon Ross /* END CSTYLED */
110347dc10d7SGordon Ross 
110447dc10d7SGordon Ross err2:
110547dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
110647dc10d7SGordon Ross err1:
110747dc10d7SGordon Ross 	mdb_free(drm_dev, sizeof (struct drm_device));
110847dc10d7SGordon Ross 	return (ret);
110947dc10d7SGordon Ross }
111047dc10d7SGordon Ross 
111147dc10d7SGordon Ross void
i915_request_list_node_help(void)111247dc10d7SGordon Ross i915_request_list_node_help(void)
111347dc10d7SGordon Ross {
111447dc10d7SGordon Ross 	mdb_printf("Print request list information for a given list pointer\n"
111547dc10d7SGordon Ross 	    "The information includes request, SeqNO. and timestamp.\n");
111647dc10d7SGordon Ross }
111747dc10d7SGordon Ross 
111847dc10d7SGordon Ross /* ARGSUSED */
111947dc10d7SGordon Ross static int
i915_request_list_node(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)112047dc10d7SGordon Ross i915_request_list_node(uintptr_t addr, uint_t flags, int argc,
112147dc10d7SGordon Ross     const mdb_arg_t *argv)
112247dc10d7SGordon Ross {
112347dc10d7SGordon Ross 	int ret = DCMD_OK;
112447dc10d7SGordon Ross 	struct list_head list;
112547dc10d7SGordon Ross 	struct drm_i915_gem_request *request;
112647dc10d7SGordon Ross 
112747dc10d7SGordon Ross 	if (!(flags & DCMD_ADDRSPEC))
112847dc10d7SGordon Ross 		return (DCMD_USAGE);
112947dc10d7SGordon Ross 
113047dc10d7SGordon Ross 	if (mdb_vread(&list, sizeof (struct list), addr) == -1) {
113147dc10d7SGordon Ross 		mdb_warn("failed to read list");
113247dc10d7SGordon Ross 		return (DCMD_ERR);
113347dc10d7SGordon Ross 	}
113447dc10d7SGordon Ross 
113547dc10d7SGordon Ross 	if (list.contain_ptr == 0) {
113647dc10d7SGordon Ross 		mdb_warn("no request!");
113747dc10d7SGordon Ross 		return (DCMD_ERR);
113847dc10d7SGordon Ross 	}
113947dc10d7SGordon Ross 
114047dc10d7SGordon Ross 	request = mdb_alloc(sizeof (struct drm_i915_gem_request), UM_SLEEP);
114147dc10d7SGordon Ross 	if (mdb_vread(request, sizeof (struct drm_i915_gem_request),
114247dc10d7SGordon Ross 	    (uintptr_t)list.contain_ptr) == -1) {
114347dc10d7SGordon Ross 		mdb_warn("failed to read request infor");
114447dc10d7SGordon Ross 		ret = DCMD_ERR;
114547dc10d7SGordon Ross 		goto err;
114647dc10d7SGordon Ross 	}
114747dc10d7SGordon Ross 
114847dc10d7SGordon Ross 	mdb_printf("0x%lx ", list.contain_ptr);
114947dc10d7SGordon Ross 	mdb_printf("    %d @ %ld\n", request->seqno, request->emitted_jiffies);
115047dc10d7SGordon Ross 
115147dc10d7SGordon Ross err:
115247dc10d7SGordon Ross 	mdb_free(request, sizeof (struct drm_i915_gem_request));
115347dc10d7SGordon Ross 	return (ret);
115447dc10d7SGordon Ross }
115547dc10d7SGordon Ross 
115647dc10d7SGordon Ross static int
request_walk_list(uintptr_t addr,const char * str)115747dc10d7SGordon Ross request_walk_list(uintptr_t addr, const char *str)
115847dc10d7SGordon Ross {
115947dc10d7SGordon Ross 	struct list_head *head;
116047dc10d7SGordon Ross 	int ret = DCMD_OK;
116147dc10d7SGordon Ross 
116247dc10d7SGordon Ross 	mdb_printf("Dump %s ring request List %p\n", str, addr);
116347dc10d7SGordon Ross 
116447dc10d7SGordon Ross 	head = mdb_alloc(sizeof (struct list_head), UM_SLEEP);
116547dc10d7SGordon Ross 	if (mdb_vread(head, sizeof (struct list_head), addr) == -1) {
116647dc10d7SGordon Ross 		mdb_warn("failed to render ring request list");
116747dc10d7SGordon Ross 		ret = DCMD_ERR;
116847dc10d7SGordon Ross 		goto err;
116947dc10d7SGordon Ross 	}
117047dc10d7SGordon Ross 
117147dc10d7SGordon Ross 	if (mdb_pwalk_dcmd("head_list", "i915_request_list_node",
117247dc10d7SGordon Ross 	    0, NULL, (uintptr_t)head->prev) == -1) {
117347dc10d7SGordon Ross 		mdb_warn("failed to walk request head_list");
117447dc10d7SGordon Ross 		ret = DCMD_ERR;
117547dc10d7SGordon Ross 		goto err;
117647dc10d7SGordon Ross 	}
117747dc10d7SGordon Ross 
117847dc10d7SGordon Ross err:
117947dc10d7SGordon Ross 	mdb_free(head, sizeof (struct list_head));
118047dc10d7SGordon Ross 	return (ret);
118147dc10d7SGordon Ross 
118247dc10d7SGordon Ross }
118347dc10d7SGordon Ross 
118447dc10d7SGordon Ross void
i915_gem_request_info_help(void)118547dc10d7SGordon Ross i915_gem_request_info_help(void)
118647dc10d7SGordon Ross {
118747dc10d7SGordon Ross 	mdb_printf("Print request list for each ring buffer\n"
118847dc10d7SGordon Ross 	    "\nSee also: \"::help i915_request_list_node\"\n");
118947dc10d7SGordon Ross }
119047dc10d7SGordon Ross 
119147dc10d7SGordon Ross /* ARGSUSED */
119247dc10d7SGordon Ross static int
i915_gem_request_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)119347dc10d7SGordon Ross i915_gem_request_info(uintptr_t addr, uint_t flags, int argc,
119447dc10d7SGordon Ross     const mdb_arg_t *argv)
119547dc10d7SGordon Ross {
119647dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
119747dc10d7SGordon Ross 	int ret = DCMD_OK;
119847dc10d7SGordon Ross 
119947dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
120047dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx, just ignore\n",
120147dc10d7SGordon Ross 		    addr);
120247dc10d7SGordon Ross 	}
120347dc10d7SGordon Ross 
120447dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
120547dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
120647dc10d7SGordon Ross 	if (ret != DCMD_OK) {
120747dc10d7SGordon Ross 		goto err;
120847dc10d7SGordon Ross 	}
120947dc10d7SGordon Ross 
121047dc10d7SGordon Ross 	ret = request_walk_list((uintptr_t)dev_priv->ring[0].request_list.next,
121147dc10d7SGordon Ross 	    "RENDER");
121247dc10d7SGordon Ross 	if (ret != DCMD_OK) {
121347dc10d7SGordon Ross 		goto err;
121447dc10d7SGordon Ross 	}
121547dc10d7SGordon Ross 	ret = request_walk_list((uintptr_t)dev_priv->ring[1].request_list.next,
121647dc10d7SGordon Ross 	    "BSD");
121747dc10d7SGordon Ross 	if (ret != DCMD_OK) {
121847dc10d7SGordon Ross 		goto err;
121947dc10d7SGordon Ross 	}
122047dc10d7SGordon Ross 	ret = request_walk_list((uintptr_t)dev_priv->ring[2].request_list.next,
122147dc10d7SGordon Ross 	    "BLT");
122247dc10d7SGordon Ross 	if (ret != DCMD_OK) {
122347dc10d7SGordon Ross 		goto err;
122447dc10d7SGordon Ross 	}
122547dc10d7SGordon Ross 
122647dc10d7SGordon Ross err:
122747dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
122847dc10d7SGordon Ross 	return (ret);
122947dc10d7SGordon Ross }
123047dc10d7SGordon Ross 
123147dc10d7SGordon Ross static int
get_hws_info(uintptr_t addr,const char * str,int index)123247dc10d7SGordon Ross get_hws_info(uintptr_t addr, const char *str, int index)
123347dc10d7SGordon Ross {
123447dc10d7SGordon Ross 	u32 *regs;
123547dc10d7SGordon Ross 	int i, ret = DCMD_OK;
123647dc10d7SGordon Ross 
123747dc10d7SGordon Ross 	regs = mdb_alloc(0x4000, UM_SLEEP);
123847dc10d7SGordon Ross 	if (mdb_vread(regs, 0x4000,
123947dc10d7SGordon Ross 	    addr) == -1) {
124047dc10d7SGordon Ross 		mdb_warn("failed to read hardware status page");
124147dc10d7SGordon Ross 		ret = DCMD_ERR;
124247dc10d7SGordon Ross 		goto err;
124347dc10d7SGordon Ross 	}
124447dc10d7SGordon Ross 
124547dc10d7SGordon Ross 	if (index < 0) {
124647dc10d7SGordon Ross 		for (i = 0; i < 4096 / sizeof (u32) / 4; i += 4) {
124747dc10d7SGordon Ross 			mdb_printf("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
124847dc10d7SGordon Ross 			    i * 4, regs[i], regs[i + 1], regs[i + 2],
124947dc10d7SGordon Ross 			    regs[i + 3]);
125047dc10d7SGordon Ross 		}
125147dc10d7SGordon Ross 	} else
125247dc10d7SGordon Ross 		mdb_printf("%s ring seqno %d \n", str, regs[index]);
125347dc10d7SGordon Ross err:
125447dc10d7SGordon Ross 	mdb_free(regs, 0x4000);
125547dc10d7SGordon Ross return (ret);
125647dc10d7SGordon Ross 
125747dc10d7SGordon Ross }
125847dc10d7SGordon Ross 
125947dc10d7SGordon Ross void
i915_ring_seqno_info_help(void)126047dc10d7SGordon Ross i915_ring_seqno_info_help(void)
126147dc10d7SGordon Ross {
126247dc10d7SGordon Ross 	mdb_printf("Print current SeqNO. for each ring buffer\n");
126347dc10d7SGordon Ross }
126447dc10d7SGordon Ross 
126547dc10d7SGordon Ross /* ARGSUSED */
126647dc10d7SGordon Ross static int
i915_ring_seqno_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)126747dc10d7SGordon Ross i915_ring_seqno_info(uintptr_t addr, uint_t flags, int argc,
126847dc10d7SGordon Ross     const mdb_arg_t *argv)
126947dc10d7SGordon Ross {
127047dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
127147dc10d7SGordon Ross 	int ret = DCMD_OK;
127247dc10d7SGordon Ross 
127347dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
127447dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
127547dc10d7SGordon Ross 		return (DCMD_OK);
127647dc10d7SGordon Ross 	}
127747dc10d7SGordon Ross 
127847dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
127947dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
128047dc10d7SGordon Ross 	if (ret != DCMD_OK) {
128147dc10d7SGordon Ross 		goto err;
128247dc10d7SGordon Ross 	}
128347dc10d7SGordon Ross 
128447dc10d7SGordon Ross 	ret = get_hws_info((uintptr_t)dev_priv->ring[0].status_page.page_addr,
128547dc10d7SGordon Ross 	    "RENDER", I915_GEM_HWS_INDEX);
128647dc10d7SGordon Ross 	if (ret != DCMD_OK) {
128747dc10d7SGordon Ross 		goto err;
128847dc10d7SGordon Ross 	}
128947dc10d7SGordon Ross 	ret = get_hws_info((uintptr_t)dev_priv->ring[1].status_page.page_addr,
129047dc10d7SGordon Ross 	    "BSD", I915_GEM_HWS_INDEX);
129147dc10d7SGordon Ross 	if (ret != DCMD_OK) {
129247dc10d7SGordon Ross 		goto err;
129347dc10d7SGordon Ross 	}
129447dc10d7SGordon Ross 	ret = get_hws_info((uintptr_t)dev_priv->ring[2].status_page.page_addr,
129547dc10d7SGordon Ross 	    "BLT", I915_GEM_HWS_INDEX);
129647dc10d7SGordon Ross 	if (ret != DCMD_OK) {
129747dc10d7SGordon Ross 		goto err;
129847dc10d7SGordon Ross 	}
129947dc10d7SGordon Ross 
130047dc10d7SGordon Ross 
130147dc10d7SGordon Ross err:
130247dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
130347dc10d7SGordon Ross 	return (ret);
130447dc10d7SGordon Ross 
130547dc10d7SGordon Ross }
130647dc10d7SGordon Ross 
130747dc10d7SGordon Ross void
i915_gem_fence_regs_info_help(void)130847dc10d7SGordon Ross i915_gem_fence_regs_info_help(void)
130947dc10d7SGordon Ross {
131047dc10d7SGordon Ross 	mdb_printf("Print current Fence registers information\n"
131147dc10d7SGordon Ross 	"The information includes object address, user pin flag, tiling mode,\n"
131247dc10d7SGordon Ross 	"size, read domain, write domain, read SeqNO, write SeqNO, fence "
131347dc10d7SGordon Ross 	"SeqNo,\n"
131447dc10d7SGordon Ross 	"catch level, dirty info, object name, pin count, fence reg number,\n"
131547dc10d7SGordon Ross 	"GTT offset, pin mappable and fault mappable.\n");
131647dc10d7SGordon Ross }
131747dc10d7SGordon Ross 
131847dc10d7SGordon Ross /* ARGSUSED */
131947dc10d7SGordon Ross static int
i915_gem_fence_regs_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)132047dc10d7SGordon Ross i915_gem_fence_regs_info(uintptr_t addr, uint_t flags, int argc,
132147dc10d7SGordon Ross     const mdb_arg_t *argv)
132247dc10d7SGordon Ross {
132347dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
132447dc10d7SGordon Ross 	int i, ret = DCMD_OK;
132547dc10d7SGordon Ross 	struct drm_i915_gem_object obj;
132647dc10d7SGordon Ross 
132747dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
132847dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
132947dc10d7SGordon Ross 		return (DCMD_OK);
133047dc10d7SGordon Ross 	}
133147dc10d7SGordon Ross 
133247dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
133347dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
133447dc10d7SGordon Ross 	if (ret != DCMD_OK) {
133547dc10d7SGordon Ross 		goto err;
133647dc10d7SGordon Ross 	}
133747dc10d7SGordon Ross 
133847dc10d7SGordon Ross 	mdb_printf("Reserved fences start = %d\n", dev_priv->fence_reg_start);
133947dc10d7SGordon Ross 	mdb_printf("Total fences = %d\n", dev_priv->num_fence_regs);
134047dc10d7SGordon Ross 
134147dc10d7SGordon Ross 	for (i = 0; i < dev_priv->num_fence_regs; i++) {
134247dc10d7SGordon Ross 
134347dc10d7SGordon Ross 		mdb_printf("Fence %d, pin count = %d, object = ",
134447dc10d7SGordon Ross 		    i, dev_priv->fence_regs[i].pin_count);
134547dc10d7SGordon Ross 
134647dc10d7SGordon Ross 		if (dev_priv->fence_regs[i].obj != NULL) {
134747dc10d7SGordon Ross 			mdb_vread(&obj, sizeof (struct drm_i915_gem_object),
134847dc10d7SGordon Ross 			    (uintptr_t)dev_priv->fence_regs[i].obj);
134947dc10d7SGordon Ross 			describe_obj(&obj);
135047dc10d7SGordon Ross 		} else {
135147dc10d7SGordon Ross 			mdb_printf("unused");
135247dc10d7SGordon Ross 		}
135347dc10d7SGordon Ross 		mdb_printf("\n");
135447dc10d7SGordon Ross 	}
135547dc10d7SGordon Ross 
135647dc10d7SGordon Ross err:
135747dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
135847dc10d7SGordon Ross 	return (ret);
135947dc10d7SGordon Ross 
136047dc10d7SGordon Ross }
136147dc10d7SGordon Ross 
136247dc10d7SGordon Ross void
i915_interrupt_info_help(void)136347dc10d7SGordon Ross i915_interrupt_info_help(void)
136447dc10d7SGordon Ross {
136547dc10d7SGordon Ross 	mdb_printf("Print debug register information\n"
136647dc10d7SGordon Ross 	    "Registers printed:\n"
136747dc10d7SGordon Ross 	    "       IER:\tInterrupt Enable Register\n"
136847dc10d7SGordon Ross 	    "       IIR:\tInterrupt Identity Register\n"
136947dc10d7SGordon Ross 	    "       IMR:\tInterrupt Mask Register\n"
137047dc10d7SGordon Ross 	    "       ISR:\tInterrupt Status Register\n");
137147dc10d7SGordon Ross }
137247dc10d7SGordon Ross 
137347dc10d7SGordon Ross /* ARGSUSED */
137447dc10d7SGordon Ross static int
i915_interrupt_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)137547dc10d7SGordon Ross i915_interrupt_info(uintptr_t addr, uint_t flags, int argc,
137647dc10d7SGordon Ross     const mdb_arg_t *argv)
137747dc10d7SGordon Ross {
137847dc10d7SGordon Ross 	struct drm_device *dev;
137947dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
138047dc10d7SGordon Ross 	struct intel_device_info info;
138147dc10d7SGordon Ross 	int pipe, ret = DCMD_OK;
138247dc10d7SGordon Ross 	uint32_t val;
138347dc10d7SGordon Ross 
138447dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
138547dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
138647dc10d7SGordon Ross 		return (DCMD_OK);
138747dc10d7SGordon Ross 	}
138847dc10d7SGordon Ross 
138947dc10d7SGordon Ross 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
139047dc10d7SGordon Ross 	ret = get_drm_dev(dev);
139147dc10d7SGordon Ross 	if (ret == DCMD_ERR)
139247dc10d7SGordon Ross 		goto err1;
139347dc10d7SGordon Ross 
139447dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
139547dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
139647dc10d7SGordon Ross 	if (ret != DCMD_OK) {
139747dc10d7SGordon Ross 		goto err2;
139847dc10d7SGordon Ross 	}
139947dc10d7SGordon Ross 
140047dc10d7SGordon Ross 	if (mdb_vread(&info, sizeof (struct intel_device_info),
140147dc10d7SGordon Ross 	    (uintptr_t)dev_priv->info) == -1) {
140247dc10d7SGordon Ross 		mdb_warn("failed to read i915 chip info");
140347dc10d7SGordon Ross 		ret = DCMD_ERR;
140447dc10d7SGordon Ross 		goto err2;
140547dc10d7SGordon Ross 	}
140647dc10d7SGordon Ross 
140747dc10d7SGordon Ross 	if (info.is_valleyview) {
140847dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)VLV_IER, &val);
140947dc10d7SGordon Ross 		if (ret == DCMD_OK)
141047dc10d7SGordon Ross 			mdb_printf("Display IER:\t%08x\n", val);
141147dc10d7SGordon Ross 
141247dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)VLV_IIR, &val);
141347dc10d7SGordon Ross 		if (ret == DCMD_OK)
141447dc10d7SGordon Ross 			mdb_printf("Display IIR:\t%08x\n", val);
141547dc10d7SGordon Ross 
141647dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)VLV_IIR_RW, &val);
141747dc10d7SGordon Ross 		if (ret == DCMD_OK)
141847dc10d7SGordon Ross 			mdb_printf("Display IIR_RW:\t%08x\n", val);
141947dc10d7SGordon Ross 
142047dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)VLV_IMR, &val);
142147dc10d7SGordon Ross 		if (ret == DCMD_OK)
142247dc10d7SGordon Ross 			mdb_printf("Display IMR:\t%08x\n", val);
142347dc10d7SGordon Ross 
142447dc10d7SGordon Ross 		for_each_pipe(pipe) {
142547dc10d7SGordon Ross 			ret = i915_read(dev_priv, PIPESTAT(pipe), &val);
142647dc10d7SGordon Ross 			if (ret == DCMD_OK)
142747dc10d7SGordon Ross 				mdb_printf("Pipe %c stat:\t%08x\n",
142847dc10d7SGordon Ross 				    pipe_name(pipe), val);
142947dc10d7SGordon Ross 		}
143047dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)VLV_MASTER_IER, &val);
143147dc10d7SGordon Ross 		if (ret == DCMD_OK)
143247dc10d7SGordon Ross 			mdb_printf("Master IER:\t%08x\n", val);
143347dc10d7SGordon Ross 
143447dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GTIER, &val);
143547dc10d7SGordon Ross 		if (ret == DCMD_OK)
143647dc10d7SGordon Ross 			mdb_printf("Render IER:\t%08x\n", val);
143747dc10d7SGordon Ross 
143847dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GTIIR, &val);
143947dc10d7SGordon Ross 		if (ret == DCMD_OK)
144047dc10d7SGordon Ross 			mdb_printf("Render IIR:\t%08x\n", val);
144147dc10d7SGordon Ross 
144247dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GTIMR, &val);
144347dc10d7SGordon Ross 		if (ret == DCMD_OK)
144447dc10d7SGordon Ross 			mdb_printf("Render IMR:\t%08x\n", val);
144547dc10d7SGordon Ross 
144647dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GEN6_PMIER, &val);
144747dc10d7SGordon Ross 		if (ret == DCMD_OK)
144847dc10d7SGordon Ross 			mdb_printf("PM IER:\t\t%08x\n", val);
144947dc10d7SGordon Ross 
145047dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GEN6_PMIIR, &val);
145147dc10d7SGordon Ross 		if (ret == DCMD_OK)
145247dc10d7SGordon Ross 			mdb_printf("PM IIR:\t\t%08x\n", val);
145347dc10d7SGordon Ross 
145447dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GEN6_PMIMR, &val);
145547dc10d7SGordon Ross 		if (ret == DCMD_OK)
145647dc10d7SGordon Ross 			mdb_printf("PM IMR:\t\t%08x\n", val);
145747dc10d7SGordon Ross 
145847dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)PORT_HOTPLUG_EN, &val);
145947dc10d7SGordon Ross 		if (ret == DCMD_OK)
146047dc10d7SGordon Ross 			mdb_printf("Port hotplug:\t%08x\n", val);
146147dc10d7SGordon Ross 
146247dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)VLV_DPFLIPSTAT, &val);
146347dc10d7SGordon Ross 		if (ret == DCMD_OK)
146447dc10d7SGordon Ross 			mdb_printf("DPFLIPSTAT:\t%08x\n", val);
146547dc10d7SGordon Ross 
146647dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)DPINVGTT, &val);
146747dc10d7SGordon Ross 		if (ret == DCMD_OK)
146847dc10d7SGordon Ross 			mdb_printf("DPINVGTT:\t%08x\n", val);
146947dc10d7SGordon Ross 	} else if (dev_priv->pch_type == PCH_NONE) {
147047dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)IER, &val);
147147dc10d7SGordon Ross 		if (ret == DCMD_OK)
147247dc10d7SGordon Ross 			mdb_printf("Interrupt enable:    %08x\n", val);
147347dc10d7SGordon Ross 
147447dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)IIR, &val);
147547dc10d7SGordon Ross 		if (ret == DCMD_OK)
147647dc10d7SGordon Ross 			mdb_printf("Interrupt identity:  %08x\n", val);
147747dc10d7SGordon Ross 
147847dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)IMR, &val);
147947dc10d7SGordon Ross 		if (ret == DCMD_OK)
148047dc10d7SGordon Ross 			mdb_printf("Interrupt mask:      %08x\n", val);
148147dc10d7SGordon Ross 
148247dc10d7SGordon Ross 		for_each_pipe(pipe) {
148347dc10d7SGordon Ross 			ret = i915_read(dev_priv, (uintptr_t)PIPESTAT(pipe),
148447dc10d7SGordon Ross 			    &val);
148547dc10d7SGordon Ross 			if (ret == DCMD_OK)
148647dc10d7SGordon Ross 				mdb_printf("Pipe %c stat:         %08x\n",
148747dc10d7SGordon Ross 				    pipe_name(pipe), val);
148847dc10d7SGordon Ross 		}
148947dc10d7SGordon Ross 	} else {
149047dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)DEIER, &val);
149147dc10d7SGordon Ross 		if (ret == DCMD_OK)
149247dc10d7SGordon Ross 			mdb_printf(
149347dc10d7SGordon Ross 			    "North Display Interrupt enable:		%08x\n",
149447dc10d7SGordon Ross 			    val);
149547dc10d7SGordon Ross 
149647dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)DEIIR, &val);
149747dc10d7SGordon Ross 		if (ret == DCMD_OK)
149847dc10d7SGordon Ross 			mdb_printf(
149947dc10d7SGordon Ross 			    "North Display Interrupt identity:	%08x\n", val);
150047dc10d7SGordon Ross 
150147dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)DEIMR, &val);
150247dc10d7SGordon Ross 		if (ret == DCMD_OK)
150347dc10d7SGordon Ross 			mdb_printf(
150447dc10d7SGordon Ross 			    "North Display Interrupt mask:		%08x\n",
150547dc10d7SGordon Ross 			    val);
150647dc10d7SGordon Ross 
150747dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)SDEIER, &val);
150847dc10d7SGordon Ross 		if (ret == DCMD_OK)
150947dc10d7SGordon Ross 			mdb_printf(
151047dc10d7SGordon Ross 			    "South Display Interrupt enable:		%08x\n",
151147dc10d7SGordon Ross 			    val);
151247dc10d7SGordon Ross 
151347dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)SDEIIR, &val);
151447dc10d7SGordon Ross 		if (ret == DCMD_OK)
151547dc10d7SGordon Ross 			mdb_printf(
151647dc10d7SGordon Ross 			    "South Display Interrupt identity:	%08x\n", val);
151747dc10d7SGordon Ross 
151847dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)SDEIMR, &val);
151947dc10d7SGordon Ross 		if (ret == DCMD_OK)
152047dc10d7SGordon Ross 			mdb_printf(
152147dc10d7SGordon Ross 			    "South Display Interrupt mask:		%08x\n",
152247dc10d7SGordon Ross 			    val);
152347dc10d7SGordon Ross 
152447dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GTIER, &val);
152547dc10d7SGordon Ross 		if (ret == DCMD_OK)
152647dc10d7SGordon Ross 			mdb_printf(
152747dc10d7SGordon Ross 			    "Graphics Interrupt enable:		%08x\n", val);
152847dc10d7SGordon Ross 
152947dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GTIIR, &val);
153047dc10d7SGordon Ross 		if (ret == DCMD_OK)
153147dc10d7SGordon Ross 			mdb_printf(
153247dc10d7SGordon Ross 			    "Graphics Interrupt identity:		%08x\n",
153347dc10d7SGordon Ross 			    val);
153447dc10d7SGordon Ross 
153547dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GTIMR, &val);
153647dc10d7SGordon Ross 		if (ret == DCMD_OK)
153747dc10d7SGordon Ross 			mdb_printf(
153847dc10d7SGordon Ross 			    "Graphics Interrupt mask:		%08x\n", val);
153947dc10d7SGordon Ross 	}
154047dc10d7SGordon Ross 	mdb_printf("Interrupts received: %d\n", dev_priv->irq_received);
154147dc10d7SGordon Ross 
154247dc10d7SGordon Ross err2:
154347dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
154447dc10d7SGordon Ross err1:
154547dc10d7SGordon Ross 	mdb_free(dev, sizeof (struct drm_device));
154647dc10d7SGordon Ross 
154747dc10d7SGordon Ross 	return (ret);
154847dc10d7SGordon Ross 
154947dc10d7SGordon Ross }
155047dc10d7SGordon Ross 
155147dc10d7SGordon Ross void
i915_hws_info_help(void)155247dc10d7SGordon Ross i915_hws_info_help(void)
155347dc10d7SGordon Ross {
155447dc10d7SGordon Ross 	mdb_printf("Print hardware status page for each RING\n");
155547dc10d7SGordon Ross }
155647dc10d7SGordon Ross 
155747dc10d7SGordon Ross /* ARGSUSED */
155847dc10d7SGordon Ross static int
i915_hws_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)155947dc10d7SGordon Ross i915_hws_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
156047dc10d7SGordon Ross {
156147dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
156247dc10d7SGordon Ross 	int ret = DCMD_OK;
156347dc10d7SGordon Ross 
156447dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
156547dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
156647dc10d7SGordon Ross 		return (DCMD_OK);
156747dc10d7SGordon Ross 	}
156847dc10d7SGordon Ross 
156947dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
157047dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
157147dc10d7SGordon Ross 	if (ret != DCMD_OK) {
157247dc10d7SGordon Ross 		goto err;
157347dc10d7SGordon Ross 	}
157447dc10d7SGordon Ross 
157547dc10d7SGordon Ross 	mdb_printf("Hardware status page for %s\n", "RENDER");
157647dc10d7SGordon Ross 	ret = get_hws_info((uintptr_t)dev_priv->ring[0].status_page.page_addr,
157747dc10d7SGordon Ross 	    "RENDER", -1);
157847dc10d7SGordon Ross 	if (ret != DCMD_OK) {
157947dc10d7SGordon Ross 		goto err;
158047dc10d7SGordon Ross 	}
158147dc10d7SGordon Ross 
158247dc10d7SGordon Ross 	mdb_printf("Hardware status page for %s\n", "BSD");
158347dc10d7SGordon Ross 	ret = get_hws_info((uintptr_t)dev_priv->ring[1].status_page.page_addr,
158447dc10d7SGordon Ross 	    "BSD", -1);
158547dc10d7SGordon Ross 	if (ret != DCMD_OK) {
158647dc10d7SGordon Ross 		goto err;
158747dc10d7SGordon Ross 	}
158847dc10d7SGordon Ross 
158947dc10d7SGordon Ross 	mdb_printf("Hardware status page for %s\n", "BLT");
159047dc10d7SGordon Ross 	ret = get_hws_info((uintptr_t)dev_priv->ring[2].status_page.page_addr,
159147dc10d7SGordon Ross 	    "BLT", -1);
159247dc10d7SGordon Ross 	if (ret != DCMD_OK) {
159347dc10d7SGordon Ross 		goto err;
159447dc10d7SGordon Ross 	}
159547dc10d7SGordon Ross 
159647dc10d7SGordon Ross err:
159747dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
159847dc10d7SGordon Ross 	return (ret);
159947dc10d7SGordon Ross 
160047dc10d7SGordon Ross }
160147dc10d7SGordon Ross 
160247dc10d7SGordon Ross void
i915_fbc_status_help(void)160347dc10d7SGordon Ross i915_fbc_status_help(void)
160447dc10d7SGordon Ross {
160547dc10d7SGordon Ross 	mdb_printf("Print the status and reason for Framebuffer Compression "
160647dc10d7SGordon Ross 	    "Enabling\n");
160747dc10d7SGordon Ross }
160847dc10d7SGordon Ross 
160947dc10d7SGordon Ross /* ARGSUSED */
161047dc10d7SGordon Ross static int
i915_fbc_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)161147dc10d7SGordon Ross i915_fbc_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
161247dc10d7SGordon Ross {
161347dc10d7SGordon Ross 	struct drm_device *dev;
161447dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
161547dc10d7SGordon Ross 	struct intel_device_info info;
161647dc10d7SGordon Ross 	int ret = DCMD_OK;
161747dc10d7SGordon Ross 	uint32_t val;
161847dc10d7SGordon Ross 
161947dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
162047dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
162147dc10d7SGordon Ross 		return (DCMD_OK);
162247dc10d7SGordon Ross 	}
162347dc10d7SGordon Ross 
162447dc10d7SGordon Ross 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
162547dc10d7SGordon Ross 	ret = get_drm_dev(dev);
162647dc10d7SGordon Ross 	if (ret == DCMD_ERR)
162747dc10d7SGordon Ross 		goto err1;
162847dc10d7SGordon Ross 
162947dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
163047dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
163147dc10d7SGordon Ross 	if (ret != DCMD_OK) {
163247dc10d7SGordon Ross 		goto err2;
163347dc10d7SGordon Ross 	}
163447dc10d7SGordon Ross 
163547dc10d7SGordon Ross 	if (mdb_vread(&info, sizeof (struct intel_device_info),
163647dc10d7SGordon Ross 	    (uintptr_t)dev_priv->info) == -1) {
163747dc10d7SGordon Ross 		mdb_warn("failed to read i915 chip info");
163847dc10d7SGordon Ross 		ret = DCMD_ERR;
163947dc10d7SGordon Ross 		goto err2;
164047dc10d7SGordon Ross 	}
164147dc10d7SGordon Ross 
164247dc10d7SGordon Ross 	if (!info.has_fbc) {
164347dc10d7SGordon Ross 		mdb_printf("FBC unsupported on this chipset\n");
164447dc10d7SGordon Ross 		goto err2;
164547dc10d7SGordon Ross 	}
164647dc10d7SGordon Ross 
164747dc10d7SGordon Ross 	if (dev_priv->pch_type != PCH_NONE) {
164847dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)ILK_DPFC_CONTROL, &val);
164947dc10d7SGordon Ross 		if (ret == DCMD_OK) {
165047dc10d7SGordon Ross 			val &= DPFC_CTL_EN;
165147dc10d7SGordon Ross 		} else {
165247dc10d7SGordon Ross 			mdb_printf("Failed to read FBC register\n");
165347dc10d7SGordon Ross 			goto err2;
165447dc10d7SGordon Ross 		}
165547dc10d7SGordon Ross 	} else if (IS_GM45(dev)) {
165647dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)DPFC_CONTROL, &val);
165747dc10d7SGordon Ross 		if (ret == DCMD_OK) {
165847dc10d7SGordon Ross 			val &= DPFC_CTL_EN;
165947dc10d7SGordon Ross 		} else {
166047dc10d7SGordon Ross 			mdb_printf("Failed to read FBC register\n");
166147dc10d7SGordon Ross 			goto err2;
166247dc10d7SGordon Ross 		}
166347dc10d7SGordon Ross 	} else if (info.is_crestline) {
166447dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)FBC_CONTROL, &val);
166547dc10d7SGordon Ross 		if (ret == DCMD_OK) {
166647dc10d7SGordon Ross 			val &= FBC_CTL_EN;
166747dc10d7SGordon Ross 		} else {
166847dc10d7SGordon Ross 			mdb_printf("Failed to read FBC register\n");
166947dc10d7SGordon Ross 			goto err2;
167047dc10d7SGordon Ross 		}
167147dc10d7SGordon Ross 	}
167247dc10d7SGordon Ross 
167347dc10d7SGordon Ross 	if (val) {
167447dc10d7SGordon Ross 		mdb_printf("FBC enabled\n");
167547dc10d7SGordon Ross 	} else {
167647dc10d7SGordon Ross 		mdb_printf("FBC disabled: ");
167747dc10d7SGordon Ross 		switch (dev_priv->no_fbc_reason) {
167847dc10d7SGordon Ross 		case FBC_NO_OUTPUT:
167947dc10d7SGordon Ross 			mdb_printf("no outputs");
168047dc10d7SGordon Ross 			break;
168147dc10d7SGordon Ross 		case FBC_STOLEN_TOO_SMALL:
168247dc10d7SGordon Ross 			mdb_printf("not enough stolen memory");
168347dc10d7SGordon Ross 			break;
168447dc10d7SGordon Ross 		case FBC_UNSUPPORTED_MODE:
168547dc10d7SGordon Ross 			mdb_printf("mode not supported");
168647dc10d7SGordon Ross 			break;
168747dc10d7SGordon Ross 		case FBC_MODE_TOO_LARGE:
168847dc10d7SGordon Ross 			mdb_printf("mode too large");
168947dc10d7SGordon Ross 			break;
169047dc10d7SGordon Ross 		case FBC_BAD_PLANE:
169147dc10d7SGordon Ross 			mdb_printf("FBC unsupported on plane");
169247dc10d7SGordon Ross 			break;
169347dc10d7SGordon Ross 		case FBC_NOT_TILED:
169447dc10d7SGordon Ross 			mdb_printf("scanout buffer not tiled");
169547dc10d7SGordon Ross 			break;
169647dc10d7SGordon Ross 		case FBC_MULTIPLE_PIPES:
169747dc10d7SGordon Ross 			mdb_printf("multiple pipes are enabled");
169847dc10d7SGordon Ross 			break;
169947dc10d7SGordon Ross 		case FBC_MODULE_PARAM:
170047dc10d7SGordon Ross 			mdb_printf("disabled per module param (default off)");
170147dc10d7SGordon Ross 			break;
170247dc10d7SGordon Ross 		default:
170347dc10d7SGordon Ross 			mdb_printf("unknown reason");
170447dc10d7SGordon Ross 		}
170547dc10d7SGordon Ross 		mdb_printf("\n");
170647dc10d7SGordon Ross 	}
170747dc10d7SGordon Ross 
170847dc10d7SGordon Ross err2:
170947dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
171047dc10d7SGordon Ross err1:
171147dc10d7SGordon Ross 	mdb_free(dev, sizeof (struct drm_device));
171247dc10d7SGordon Ross 
171347dc10d7SGordon Ross 	return (ret);
171447dc10d7SGordon Ross }
171547dc10d7SGordon Ross 
171647dc10d7SGordon Ross /* ARGSUSED */
171747dc10d7SGordon Ross static int
i915_sr_status(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)171847dc10d7SGordon Ross i915_sr_status(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
171947dc10d7SGordon Ross {
172047dc10d7SGordon Ross 	struct drm_device *dev;
172147dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
172247dc10d7SGordon Ross 	struct intel_device_info info;
172347dc10d7SGordon Ross 	int ret = DCMD_OK;
172447dc10d7SGordon Ross 	uint32_t val = 0;
172547dc10d7SGordon Ross 
172647dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
172747dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
172847dc10d7SGordon Ross 		return (DCMD_OK);
172947dc10d7SGordon Ross 	}
173047dc10d7SGordon Ross 
173147dc10d7SGordon Ross 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
173247dc10d7SGordon Ross 	ret = get_drm_dev(dev);
173347dc10d7SGordon Ross 	if (ret == DCMD_ERR)
173447dc10d7SGordon Ross 		goto err1;
173547dc10d7SGordon Ross 
173647dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
173747dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
173847dc10d7SGordon Ross 	if (ret != DCMD_OK) {
173947dc10d7SGordon Ross 		goto err2;
174047dc10d7SGordon Ross 	}
174147dc10d7SGordon Ross 
174247dc10d7SGordon Ross 	if (mdb_vread(&info, sizeof (struct intel_device_info),
174347dc10d7SGordon Ross 	    (uintptr_t)dev_priv->info) == -1) {
174447dc10d7SGordon Ross 		mdb_warn("failed to read i915 chip info");
174547dc10d7SGordon Ross 		ret = DCMD_ERR;
174647dc10d7SGordon Ross 		goto err2;
174747dc10d7SGordon Ross 	}
174847dc10d7SGordon Ross 
174947dc10d7SGordon Ross 	if (dev_priv->pch_type != PCH_NONE) {
175047dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)WM1_LP_ILK, &val);
175147dc10d7SGordon Ross 		if (ret == DCMD_OK) {
175247dc10d7SGordon Ross 			val &= WM1_LP_SR_EN;
175347dc10d7SGordon Ross 		} else {
175447dc10d7SGordon Ross 			mdb_printf("Failed to read sr register\n");
175547dc10d7SGordon Ross 			goto err2;
175647dc10d7SGordon Ross 		}
175747dc10d7SGordon Ross 	} else if (info.is_crestline || IS_I945G(dev) || info.is_i945gm) {
175847dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)FW_BLC_SELF, &val);
175947dc10d7SGordon Ross 		if (ret == DCMD_OK) {
176047dc10d7SGordon Ross 			val &= FW_BLC_SELF_EN;
176147dc10d7SGordon Ross 		} else {
176247dc10d7SGordon Ross 			mdb_printf("Failed to read sr register\n");
176347dc10d7SGordon Ross 			goto err2;
176447dc10d7SGordon Ross 		}
176547dc10d7SGordon Ross 	} else if (IS_I915GM(dev)) {
176647dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)INSTPM, &val);
176747dc10d7SGordon Ross 		if (ret == DCMD_OK) {
176847dc10d7SGordon Ross 			val &= INSTPM_SELF_EN;
176947dc10d7SGordon Ross 		} else {
177047dc10d7SGordon Ross 			mdb_printf("Failed to read sr register\n");
177147dc10d7SGordon Ross 			goto err2;
177247dc10d7SGordon Ross 		}
177347dc10d7SGordon Ross 	} else if (info.is_pineview) {
177447dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)DSPFW3, &val);
177547dc10d7SGordon Ross 		if (ret == DCMD_OK) {
177647dc10d7SGordon Ross 			val &= PINEVIEW_SELF_REFRESH_EN;
177747dc10d7SGordon Ross 		} else {
177847dc10d7SGordon Ross 			mdb_printf("Failed to read sr register\n");
177947dc10d7SGordon Ross 			goto err2;
178047dc10d7SGordon Ross 		}
178147dc10d7SGordon Ross 	}
178247dc10d7SGordon Ross 
178347dc10d7SGordon Ross 	mdb_printf("self-refresh: %s\n",
178447dc10d7SGordon Ross 	    val ? "enabled" : "disabled");
178547dc10d7SGordon Ross 
178647dc10d7SGordon Ross err2:
178747dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
178847dc10d7SGordon Ross err1:
178947dc10d7SGordon Ross 	mdb_free(dev, sizeof (struct drm_device));
179047dc10d7SGordon Ross 
179147dc10d7SGordon Ross 	return (ret);
179247dc10d7SGordon Ross }
179347dc10d7SGordon Ross 
179447dc10d7SGordon Ross void
i915_gem_framebuffer_info_help(void)179547dc10d7SGordon Ross i915_gem_framebuffer_info_help(void)
179647dc10d7SGordon Ross {
179747dc10d7SGordon Ross 	mdb_printf("Print console framebuffer information\n"
179847dc10d7SGordon Ross 	    "The information includes width, height, depth,\n"
179947dc10d7SGordon Ross 	    "bits_per_pixel and object structure address\n");
180047dc10d7SGordon Ross }
180147dc10d7SGordon Ross 
180247dc10d7SGordon Ross /* ARGSUSED */
180347dc10d7SGordon Ross static int
i915_gem_framebuffer_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)180447dc10d7SGordon Ross i915_gem_framebuffer_info(uintptr_t addr, uint_t flags, int argc,
180547dc10d7SGordon Ross     const mdb_arg_t *argv)
180647dc10d7SGordon Ross {
180747dc10d7SGordon Ross 	struct drm_device *dev;
180847dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
180947dc10d7SGordon Ross 	struct intel_fbdev fbdev;
181047dc10d7SGordon Ross 	struct drm_framebuffer fb;
181147dc10d7SGordon Ross 	int ret = DCMD_OK;
181247dc10d7SGordon Ross 
181347dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
181447dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
181547dc10d7SGordon Ross 		return (DCMD_OK);
181647dc10d7SGordon Ross 	}
181747dc10d7SGordon Ross 
181847dc10d7SGordon Ross 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
181947dc10d7SGordon Ross 	ret = get_drm_dev(dev);
182047dc10d7SGordon Ross 	if (ret == DCMD_ERR)
182147dc10d7SGordon Ross 		goto err1;
182247dc10d7SGordon Ross 
182347dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
182447dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
182547dc10d7SGordon Ross 	if (ret != DCMD_OK) {
182647dc10d7SGordon Ross 		goto err2;
182747dc10d7SGordon Ross 	}
182847dc10d7SGordon Ross 
182947dc10d7SGordon Ross 	if (mdb_vread(&fbdev, sizeof (struct intel_fbdev),
183047dc10d7SGordon Ross 	    (uintptr_t)dev_priv->fbdev) == -1) {
183147dc10d7SGordon Ross 		mdb_warn("failed to read intel_fbdev info");
183247dc10d7SGordon Ross 		ret = DCMD_ERR;
183347dc10d7SGordon Ross 		goto err2;
183447dc10d7SGordon Ross 	}
183547dc10d7SGordon Ross 
183647dc10d7SGordon Ross 	if (mdb_vread(&fb, sizeof (struct drm_framebuffer),
183747dc10d7SGordon Ross 	    (uintptr_t)fbdev.helper.fb) == -1) {
183847dc10d7SGordon Ross 		mdb_warn("failed to read framebuffer info");
183947dc10d7SGordon Ross 		ret = DCMD_ERR;
184047dc10d7SGordon Ross 		goto err2;
184147dc10d7SGordon Ross 	}
184247dc10d7SGordon Ross 
184347dc10d7SGordon Ross 	mdb_printf("fbcon size: %d x %d, depth %d, %d bpp, obj %p",
184447dc10d7SGordon Ross 	    fb.width,
184547dc10d7SGordon Ross 	    fb.height,
184647dc10d7SGordon Ross 	    fb.depth,
184747dc10d7SGordon Ross 	    fb.bits_per_pixel,
184847dc10d7SGordon Ross 	    fb.base);
184947dc10d7SGordon Ross 	mdb_printf("\n");
185047dc10d7SGordon Ross 
185147dc10d7SGordon Ross err2:
185247dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
185347dc10d7SGordon Ross err1:
185447dc10d7SGordon Ross 	mdb_free(dev, sizeof (struct drm_device));
185547dc10d7SGordon Ross 
185647dc10d7SGordon Ross 	return (ret);
185747dc10d7SGordon Ross }
185847dc10d7SGordon Ross 
185947dc10d7SGordon Ross /* ARGSUSED */
186047dc10d7SGordon Ross static int
i915_gen6_forcewake_count_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)186147dc10d7SGordon Ross i915_gen6_forcewake_count_info(uintptr_t addr, uint_t flags, int argc,
186247dc10d7SGordon Ross     const mdb_arg_t *argv)
186347dc10d7SGordon Ross {
186447dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
186547dc10d7SGordon Ross 	int ret = DCMD_OK;
186647dc10d7SGordon Ross 	unsigned forcewake_count;
186747dc10d7SGordon Ross 
186847dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
186947dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
187047dc10d7SGordon Ross 		return (DCMD_OK);
187147dc10d7SGordon Ross 	}
187247dc10d7SGordon Ross 
187347dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
187447dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
187547dc10d7SGordon Ross 	if (ret != DCMD_OK) {
187647dc10d7SGordon Ross 		goto err;
187747dc10d7SGordon Ross 	}
187847dc10d7SGordon Ross 
187947dc10d7SGordon Ross 	forcewake_count = dev_priv->forcewake_count;
188047dc10d7SGordon Ross 
188147dc10d7SGordon Ross 	mdb_printf("forcewake count = %u\n", forcewake_count);
188247dc10d7SGordon Ross 
188347dc10d7SGordon Ross err:
188447dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
188547dc10d7SGordon Ross 
188647dc10d7SGordon Ross 	return (ret);
188747dc10d7SGordon Ross }
188847dc10d7SGordon Ross 
swizzle_string(unsigned swizzle)188947dc10d7SGordon Ross static const char *swizzle_string(unsigned swizzle)
189047dc10d7SGordon Ross {
189147dc10d7SGordon Ross 	switch (swizzle) {
189247dc10d7SGordon Ross 	case I915_BIT_6_SWIZZLE_NONE:
189347dc10d7SGordon Ross 		return ("none");
189447dc10d7SGordon Ross 	case I915_BIT_6_SWIZZLE_9:
189547dc10d7SGordon Ross 		return ("bit9");
189647dc10d7SGordon Ross 	case I915_BIT_6_SWIZZLE_9_10:
189747dc10d7SGordon Ross 		return ("bit9/bit10");
189847dc10d7SGordon Ross 	case I915_BIT_6_SWIZZLE_9_11:
189947dc10d7SGordon Ross 		return ("bit9/bit11");
190047dc10d7SGordon Ross 	case I915_BIT_6_SWIZZLE_9_10_11:
190147dc10d7SGordon Ross 		return ("bit9/bit10/bit11");
190247dc10d7SGordon Ross 	case I915_BIT_6_SWIZZLE_9_17:
190347dc10d7SGordon Ross 		return ("bit9/bit17");
190447dc10d7SGordon Ross 	case I915_BIT_6_SWIZZLE_9_10_17:
190547dc10d7SGordon Ross 		return ("bit9/bit10/bit17");
190647dc10d7SGordon Ross 	case I915_BIT_6_SWIZZLE_UNKNOWN:
190747dc10d7SGordon Ross 		return ("unkown");
190847dc10d7SGordon Ross 	}
190947dc10d7SGordon Ross 
191047dc10d7SGordon Ross 	return ("bug");
191147dc10d7SGordon Ross }
191247dc10d7SGordon Ross 
191347dc10d7SGordon Ross void
i915_swizzle_info_help(void)191447dc10d7SGordon Ross i915_swizzle_info_help(void)
191547dc10d7SGordon Ross {
191647dc10d7SGordon Ross 	mdb_printf("Print object swizzle information\n"
191747dc10d7SGordon Ross 	    "Registers printed:\n"
191847dc10d7SGordon Ross 	    "       TILECTL:\tTile Control\n"
191947dc10d7SGordon Ross 	    "       ARB_MODE:\tArbiter Mode Control Register\n"
192047dc10d7SGordon Ross 	    "       DISP_ARB_CTL:\tDisplay Arbiter Control\n");
192147dc10d7SGordon Ross 
192247dc10d7SGordon Ross }
192347dc10d7SGordon Ross 
192447dc10d7SGordon Ross /* ARGSUSED */
192547dc10d7SGordon Ross static int
i915_swizzle_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)192647dc10d7SGordon Ross i915_swizzle_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
192747dc10d7SGordon Ross {
192847dc10d7SGordon Ross 	struct drm_device *dev;
192947dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
193047dc10d7SGordon Ross 	struct intel_device_info info;
193147dc10d7SGordon Ross 	int ret = DCMD_OK;
193247dc10d7SGordon Ross 	uint32_t val = 0;
193347dc10d7SGordon Ross 
193447dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
193547dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
193647dc10d7SGordon Ross 		return (DCMD_OK);
193747dc10d7SGordon Ross 	}
193847dc10d7SGordon Ross 
193947dc10d7SGordon Ross 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
194047dc10d7SGordon Ross 	ret = get_drm_dev(dev);
194147dc10d7SGordon Ross 	if (ret == DCMD_ERR)
194247dc10d7SGordon Ross 		goto err1;
194347dc10d7SGordon Ross 
194447dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
194547dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
194647dc10d7SGordon Ross 	if (ret != DCMD_OK) {
194747dc10d7SGordon Ross 		goto err2;
194847dc10d7SGordon Ross 	}
194947dc10d7SGordon Ross 
195047dc10d7SGordon Ross 	if (mdb_vread(&info, sizeof (struct intel_device_info),
195147dc10d7SGordon Ross 	    (uintptr_t)dev_priv->info) == -1) {
195247dc10d7SGordon Ross 		mdb_warn("failed to read i915 chip info");
195347dc10d7SGordon Ross 		ret = DCMD_ERR;
195447dc10d7SGordon Ross 		goto err2;
195547dc10d7SGordon Ross 	}
195647dc10d7SGordon Ross 
195747dc10d7SGordon Ross 	mdb_printf("bit6 swizzle for X-tiling = %s\n",
195847dc10d7SGordon Ross 	    swizzle_string(dev_priv->mm.bit_6_swizzle_x));
195947dc10d7SGordon Ross 	mdb_printf("bit6 swizzle for Y-tiling = %s\n",
196047dc10d7SGordon Ross 	    swizzle_string(dev_priv->mm.bit_6_swizzle_y));
196147dc10d7SGordon Ross 
196247dc10d7SGordon Ross 	if ((info.gen == 3) || (info.gen == 4)) {
196347dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)DCC, &val);
196447dc10d7SGordon Ross 		if (ret == DCMD_OK)
196547dc10d7SGordon Ross 			mdb_printf("DDC = 0x%08x\n", val);
196647dc10d7SGordon Ross 
196747dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)C0DRB3, &val);
196847dc10d7SGordon Ross 		if (ret == DCMD_OK)
196947dc10d7SGordon Ross 			mdb_printf("C0DRB3 = 0x%04x\n", val);
197047dc10d7SGordon Ross 
197147dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)C1DRB3, &val);
197247dc10d7SGordon Ross 		if (ret == DCMD_OK)
197347dc10d7SGordon Ross 			mdb_printf("C1DRB3 = 0x%04x\n", val);
197447dc10d7SGordon Ross 
197547dc10d7SGordon Ross 	} else if ((info.gen == 6) || (info.gen == 7)) {
197647dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)MAD_DIMM_C0, &val);
197747dc10d7SGordon Ross 		if (ret == DCMD_OK)
197847dc10d7SGordon Ross 			mdb_printf("MAD_DIMM_C0 = 0x%08x\n", val);
197947dc10d7SGordon Ross 
198047dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)MAD_DIMM_C1, &val);
198147dc10d7SGordon Ross 		if (ret == DCMD_OK)
198247dc10d7SGordon Ross 			mdb_printf("MAD_DIMM_C1 = 0x%08x\n", val);
198347dc10d7SGordon Ross 
198447dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)MAD_DIMM_C2, &val);
198547dc10d7SGordon Ross 		if (ret == DCMD_OK)
198647dc10d7SGordon Ross 			mdb_printf("MAD_DIMM_C2 = 0x%08x\n", val);
198747dc10d7SGordon Ross 
198847dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)TILECTL, &val);
198947dc10d7SGordon Ross 		if (ret == DCMD_OK)
199047dc10d7SGordon Ross 			mdb_printf("TILECTL = 0x%08x\n", val);
199147dc10d7SGordon Ross 
199247dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)ARB_MODE, &val);
199347dc10d7SGordon Ross 		if (ret == DCMD_OK)
199447dc10d7SGordon Ross 			mdb_printf("ARB_MODE = 0x%08x\n", val);
199547dc10d7SGordon Ross 
199647dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)DISP_ARB_CTL, &val);
199747dc10d7SGordon Ross 		if (ret == DCMD_OK)
199847dc10d7SGordon Ross 			mdb_printf("DISP_ARB_CTL = 0x%08x\n", val);
199947dc10d7SGordon Ross 
200047dc10d7SGordon Ross 	}
200147dc10d7SGordon Ross 
200247dc10d7SGordon Ross err2:
200347dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
200447dc10d7SGordon Ross err1:
200547dc10d7SGordon Ross 	mdb_free(dev, sizeof (struct drm_device));
200647dc10d7SGordon Ross 
200747dc10d7SGordon Ross 	return (ret);
200847dc10d7SGordon Ross }
200947dc10d7SGordon Ross 
201047dc10d7SGordon Ross void
i915_ppgtt_info_help(void)201147dc10d7SGordon Ross i915_ppgtt_info_help(void)
201247dc10d7SGordon Ross {
201347dc10d7SGordon Ross 	mdb_printf("Print Per-Process GTT (PPGTT) information\n"
201447dc10d7SGordon Ross 	    "Registers printed:\n"
201547dc10d7SGordon Ross 	    "       GFX_MODE:\tGraphics Mode Register\n"
201647dc10d7SGordon Ross 	    "       PP_DIR_BASE:\tPage Directory Base Register\n"
201747dc10d7SGordon Ross 	    "       ECOCHK:\tMain Graphic Arbiter Misc Register\n");
201847dc10d7SGordon Ross }
201947dc10d7SGordon Ross 
202047dc10d7SGordon Ross /* ARGSUSED */
202147dc10d7SGordon Ross static int
i915_ppgtt_info(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)202247dc10d7SGordon Ross i915_ppgtt_info(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
202347dc10d7SGordon Ross {
202447dc10d7SGordon Ross 	struct drm_device *dev;
202547dc10d7SGordon Ross 	struct drm_i915_private *dev_priv;
202647dc10d7SGordon Ross 	struct intel_device_info info;
202747dc10d7SGordon Ross 	int i, ret = DCMD_OK;
202847dc10d7SGordon Ross 	uint32_t val = 0;
202947dc10d7SGordon Ross 
203047dc10d7SGordon Ross 	if (flags & DCMD_ADDRSPEC) {
203147dc10d7SGordon Ross 		mdb_printf("don't need to set address 0x%lx\n", addr);
203247dc10d7SGordon Ross 		return (DCMD_OK);
203347dc10d7SGordon Ross 	}
203447dc10d7SGordon Ross 
203547dc10d7SGordon Ross 	dev = mdb_alloc(sizeof (struct drm_device), UM_SLEEP);
203647dc10d7SGordon Ross 	ret = get_drm_dev(dev);
203747dc10d7SGordon Ross 	if (ret == DCMD_ERR)
203847dc10d7SGordon Ross 		goto err1;
203947dc10d7SGordon Ross 
204047dc10d7SGordon Ross 	dev_priv = mdb_alloc(sizeof (struct drm_i915_private), UM_SLEEP);
204147dc10d7SGordon Ross 	ret = get_i915_private(dev_priv);
204247dc10d7SGordon Ross 	if (ret != DCMD_OK) {
204347dc10d7SGordon Ross 		goto err2;
204447dc10d7SGordon Ross 	}
204547dc10d7SGordon Ross 
204647dc10d7SGordon Ross 	if (mdb_vread(&info, sizeof (struct intel_device_info),
204747dc10d7SGordon Ross 	    (uintptr_t)dev_priv->info) == -1) {
204847dc10d7SGordon Ross 		mdb_warn("failed to read i915 chip info");
204947dc10d7SGordon Ross 		ret = DCMD_ERR;
205047dc10d7SGordon Ross 		goto err2;
205147dc10d7SGordon Ross 	}
205247dc10d7SGordon Ross 
205347dc10d7SGordon Ross 	if (info.gen == 6) {
205447dc10d7SGordon Ross 		ret = i915_read(dev_priv, (uintptr_t)GFX_MODE, &val);
205547dc10d7SGordon Ross 		if (ret == DCMD_OK)
205647dc10d7SGordon Ross 			mdb_printf("GFX_MODE: 0x%08x\n", val);
205747dc10d7SGordon Ross 	}
205847dc10d7SGordon Ross 
205947dc10d7SGordon Ross 	for (i = 0; i < 3; i ++) {
206047dc10d7SGordon Ross 		mdb_printf("RING %d\n", i);
206147dc10d7SGordon Ross 		if (info.gen == 7) {
206247dc10d7SGordon Ross 			ret = i915_read(dev_priv,
206347dc10d7SGordon Ross 			    (uintptr_t)(dev_priv->ring[i].mmio_base + 0x29c),
206447dc10d7SGordon Ross 			    &val);
206547dc10d7SGordon Ross 			if (ret == DCMD_OK)
206647dc10d7SGordon Ross 				mdb_printf("GFX_MODE: 0x%08x\n", val);
206747dc10d7SGordon Ross 		}
206847dc10d7SGordon Ross 		ret = i915_read(dev_priv,
206947dc10d7SGordon Ross 		    (uintptr_t)(dev_priv->ring[i].mmio_base + 0x228), &val);
207047dc10d7SGordon Ross 		if (ret == DCMD_OK)
207147dc10d7SGordon Ross 			mdb_printf("PP_DIR_BASE: 0x%08x\n", val);
207247dc10d7SGordon Ross 
207347dc10d7SGordon Ross 		ret = i915_read(dev_priv,
207447dc10d7SGordon Ross 		    (uintptr_t)(dev_priv->ring[i].mmio_base + 0x518), &val);
207547dc10d7SGordon Ross 		if (ret == DCMD_OK)
207647dc10d7SGordon Ross 			mdb_printf("PP_DIR_BASE_READ: 0x%08x\n", val);
207747dc10d7SGordon Ross 
207847dc10d7SGordon Ross 		ret = i915_read(dev_priv,
207947dc10d7SGordon Ross 		    (uintptr_t)(dev_priv->ring[i].mmio_base + 0x220), &val);
208047dc10d7SGordon Ross 		if (ret == DCMD_OK)
208147dc10d7SGordon Ross 			mdb_printf("PP_DIR_DCLV: 0x%08x\n", val);
208247dc10d7SGordon Ross 	}
208347dc10d7SGordon Ross 
208447dc10d7SGordon Ross 	if (dev_priv->mm.aliasing_ppgtt) {
208547dc10d7SGordon Ross 		struct i915_hw_ppgtt ppgtt;
208647dc10d7SGordon Ross 		if (mdb_vread(&ppgtt, sizeof (struct i915_hw_ppgtt),
208747dc10d7SGordon Ross 		    (uintptr_t)dev_priv->mm.aliasing_ppgtt) == -1) {
208847dc10d7SGordon Ross 			mdb_warn("failed to read aliasing_ppgtt info");
208947dc10d7SGordon Ross 			ret = DCMD_ERR;
209047dc10d7SGordon Ross 			goto err2;
209147dc10d7SGordon Ross 		}
209247dc10d7SGordon Ross 
209347dc10d7SGordon Ross 		mdb_printf("aliasing PPGTT:\n");
209447dc10d7SGordon Ross 		mdb_printf("pd gtt offset: 0x%08x\n", ppgtt.pd_offset);
209547dc10d7SGordon Ross 	}
209647dc10d7SGordon Ross 
209747dc10d7SGordon Ross 	ret = i915_read(dev_priv, (uintptr_t)GAM_ECOCHK, &val);
209847dc10d7SGordon Ross 	if (ret == DCMD_OK)
209947dc10d7SGordon Ross 		mdb_printf("ECOCHK: 0x%08x\n", val);
210047dc10d7SGordon Ross 
210147dc10d7SGordon Ross err2:
210247dc10d7SGordon Ross 	mdb_free(dev_priv, sizeof (struct drm_i915_private));
210347dc10d7SGordon Ross err1:
210447dc10d7SGordon Ross 	mdb_free(dev, sizeof (struct drm_device));
210547dc10d7SGordon Ross 
210647dc10d7SGordon Ross 	return (ret);
210747dc10d7SGordon Ross }
210847dc10d7SGordon Ross 
210947dc10d7SGordon Ross /*
211047dc10d7SGordon Ross  * MDB module linkage information:
211147dc10d7SGordon Ross  *
211247dc10d7SGordon Ross  * We declare a list of structures describing our dcmds, a list of structures
211347dc10d7SGordon Ross  * describing our walkers, and a function named _mdb_init to return a pointer
211447dc10d7SGordon Ross  * to our module information.
211547dc10d7SGordon Ross  */
211647dc10d7SGordon Ross 
211747dc10d7SGordon Ross static const mdb_dcmd_t dcmds[] = {
211847dc10d7SGordon Ross 	{
211947dc10d7SGordon Ross 		"i915_pciid",
212047dc10d7SGordon Ross 		"?",
212147dc10d7SGordon Ross 		"pciid information",
212247dc10d7SGordon Ross 		i915_pciid,
212347dc10d7SGordon Ross 		i915_pciid_help
212447dc10d7SGordon Ross 	},
212547dc10d7SGordon Ross 	{
212647dc10d7SGordon Ross 		"i915_gtt_total",
212747dc10d7SGordon Ross 		"?",
212847dc10d7SGordon Ross 		"get gtt total size",
212947dc10d7SGordon Ross 		i915_gtt_total,
213047dc10d7SGordon Ross 		i915_gtt_total_help
213147dc10d7SGordon Ross 	},
213247dc10d7SGordon Ross 	{
213347dc10d7SGordon Ross 		"i915_obj_list",
213447dc10d7SGordon Ross 		"[-aibu]",
213547dc10d7SGordon Ross 		"i915 objects list information",
213647dc10d7SGordon Ross 		i915_obj_list,
213747dc10d7SGordon Ross 		i915_obj_list_help
213847dc10d7SGordon Ross 	},
213947dc10d7SGordon Ross 	{
214047dc10d7SGordon Ross 		"i915_obj_list_node",
214147dc10d7SGordon Ross 		":",
214247dc10d7SGordon Ross 		"i915 objects list node information",
214347dc10d7SGordon Ross 		i915_obj_list_node,
214447dc10d7SGordon Ross 		i915_obj_list_node_help
214547dc10d7SGordon Ross 	},
214647dc10d7SGordon Ross 	{
214747dc10d7SGordon Ross 		"i915_ringbuffer_info",
214847dc10d7SGordon Ross 		"[-lrs]",
214947dc10d7SGordon Ross 		"i915 ring buffer information",
215047dc10d7SGordon Ross 		i915_ringbuffer_info,
215147dc10d7SGordon Ross 		i915_ringbuffer_info_help
215247dc10d7SGordon Ross 	},
215347dc10d7SGordon Ross 	{
215447dc10d7SGordon Ross 		"i915_gtt_dump",
215547dc10d7SGordon Ross 		"?",
215647dc10d7SGordon Ross 		"dump gtt_dump_add address",
215747dc10d7SGordon Ross 		i915_gtt_dump,
215847dc10d7SGordon Ross 		i915_gtt_dump_help
215947dc10d7SGordon Ross 	},
216047dc10d7SGordon Ross 	{
216147dc10d7SGordon Ross 		"i915_register_read",
216247dc10d7SGordon Ross 		":",
216347dc10d7SGordon Ross 		"read i915 register",
216447dc10d7SGordon Ross 		i915_register_read,
216547dc10d7SGordon Ross 		i915_register_read_help
216647dc10d7SGordon Ross 	},
216747dc10d7SGordon Ross 	{
216847dc10d7SGordon Ross 		"i915_error_reg_dump",
216947dc10d7SGordon Ross 		"?",
217047dc10d7SGordon Ross 		"i915 error registers dump",
217147dc10d7SGordon Ross 		i915_error_reg_dump,
217247dc10d7SGordon Ross 		i915_error_reg_dump_help
217347dc10d7SGordon Ross 	},
217447dc10d7SGordon Ross 	{
217547dc10d7SGordon Ross 		"i915_obj_history",
217647dc10d7SGordon Ross 		":",
217747dc10d7SGordon Ross 		"i915 objects track information",
217847dc10d7SGordon Ross 		i915_obj_history,
217947dc10d7SGordon Ross 		i915_obj_history_help
218047dc10d7SGordon Ross 	},
218147dc10d7SGordon Ross 	{
218247dc10d7SGordon Ross 		"i915_batch_history",
218347dc10d7SGordon Ross 		"?",
218447dc10d7SGordon Ross 		"i915 objects track information",
218547dc10d7SGordon Ross 		i915_batch_history,
218647dc10d7SGordon Ross 		i915_batch_history_help
218747dc10d7SGordon Ross 	},
218847dc10d7SGordon Ross 	{
218947dc10d7SGordon Ross 		"i915_capabilities",
219047dc10d7SGordon Ross 		"?",
219147dc10d7SGordon Ross 		"i915 capabilities information",
219247dc10d7SGordon Ross 		i915_capabilities,
219347dc10d7SGordon Ross 		i915_capabilities_help
219447dc10d7SGordon Ross 	},
219547dc10d7SGordon Ross 	{
219647dc10d7SGordon Ross 		"i915_request_list_node",
219747dc10d7SGordon Ross 		":",
219847dc10d7SGordon Ross 		"i915 request list node information",
219947dc10d7SGordon Ross 		i915_request_list_node,
220047dc10d7SGordon Ross 		i915_request_list_node_help
220147dc10d7SGordon Ross 	},
220247dc10d7SGordon Ross 	{
220347dc10d7SGordon Ross 		"i915_gem_request",
220447dc10d7SGordon Ross 		"?",
220547dc10d7SGordon Ross 		"i915 gem request information",
220647dc10d7SGordon Ross 		i915_gem_request_info,
220747dc10d7SGordon Ross 		i915_gem_request_info_help
220847dc10d7SGordon Ross 	},
220947dc10d7SGordon Ross 	{
221047dc10d7SGordon Ross 		"i915_ring_seqno",
221147dc10d7SGordon Ross 		"?",
221247dc10d7SGordon Ross 		"ring seqno information",
221347dc10d7SGordon Ross 		i915_ring_seqno_info,
221447dc10d7SGordon Ross 		i915_ring_seqno_info_help
221547dc10d7SGordon Ross 	},
221647dc10d7SGordon Ross 	{
221747dc10d7SGordon Ross 		"i915_gem_fence_regs",
221847dc10d7SGordon Ross 		"?",
221947dc10d7SGordon Ross 		"fence register information",
222047dc10d7SGordon Ross 		i915_gem_fence_regs_info,
222147dc10d7SGordon Ross 		i915_gem_fence_regs_info_help
222247dc10d7SGordon Ross 	},
222347dc10d7SGordon Ross 	{
222447dc10d7SGordon Ross 		"i915_interrupt",
222547dc10d7SGordon Ross 		"?",
222647dc10d7SGordon Ross 		"interrupt information",
222747dc10d7SGordon Ross 		i915_interrupt_info,
222847dc10d7SGordon Ross 		i915_interrupt_info_help
222947dc10d7SGordon Ross 	},
223047dc10d7SGordon Ross 	{
223147dc10d7SGordon Ross 		"i915_gem_hws",
223247dc10d7SGordon Ross 		"?",
223347dc10d7SGordon Ross 		"hardware status page",
223447dc10d7SGordon Ross 		i915_hws_info,
223547dc10d7SGordon Ross 		i915_hws_info_help
223647dc10d7SGordon Ross 	},
223747dc10d7SGordon Ross 	{
223847dc10d7SGordon Ross 		"i915_fbc_status",
223947dc10d7SGordon Ross 		"?",
224047dc10d7SGordon Ross 		"framebuffer compression information",
224147dc10d7SGordon Ross 		i915_fbc_status,
224247dc10d7SGordon Ross 		i915_fbc_status_help
224347dc10d7SGordon Ross 	},
224447dc10d7SGordon Ross 	{
224547dc10d7SGordon Ross 		"i915_sr_status",
224647dc10d7SGordon Ross 		"?",
224747dc10d7SGordon Ross 		"Print self-refresh status",
224847dc10d7SGordon Ross 		i915_sr_status,
224947dc10d7SGordon Ross 		NULL
225047dc10d7SGordon Ross 	},
225147dc10d7SGordon Ross 	{
225247dc10d7SGordon Ross 		"i915_gem_framebuffer",
225347dc10d7SGordon Ross 		"?",
225447dc10d7SGordon Ross 		"Print framebuffer information",
225547dc10d7SGordon Ross 		i915_gem_framebuffer_info,
225647dc10d7SGordon Ross 		i915_gem_framebuffer_info_help
225747dc10d7SGordon Ross 	},
225847dc10d7SGordon Ross 	{
225947dc10d7SGordon Ross 		"i915_gen6_forcewake_count",
226047dc10d7SGordon Ross 		"?",
226147dc10d7SGordon Ross 		"Print forcewake count",
226247dc10d7SGordon Ross 		i915_gen6_forcewake_count_info,
226347dc10d7SGordon Ross 		NULL
226447dc10d7SGordon Ross 	},
226547dc10d7SGordon Ross 	{
226647dc10d7SGordon Ross 		"i915_swizzle",
226747dc10d7SGordon Ross 		"?",
226847dc10d7SGordon Ross 		"Print swizzle information",
226947dc10d7SGordon Ross 		i915_swizzle_info,
227047dc10d7SGordon Ross 		i915_swizzle_info_help
227147dc10d7SGordon Ross 	},
227247dc10d7SGordon Ross 	{
227347dc10d7SGordon Ross 		"i915_ppgtt",
227447dc10d7SGordon Ross 		"?",
227547dc10d7SGordon Ross 		"Print ppgtt information",
227647dc10d7SGordon Ross 		i915_ppgtt_info,
227747dc10d7SGordon Ross 		i915_ppgtt_info_help
227847dc10d7SGordon Ross 	},
227947dc10d7SGordon Ross 
228047dc10d7SGordon Ross 	{ NULL }
228147dc10d7SGordon Ross };
228247dc10d7SGordon Ross 
228347dc10d7SGordon Ross static const mdb_walker_t walkers[] = {
228447dc10d7SGordon Ross 	{
228547dc10d7SGordon Ross 		"head_list",
228647dc10d7SGordon Ross 		"walk head list",
228747dc10d7SGordon Ross 		head_list_walk_init,
228847dc10d7SGordon Ross 		head_list_walk_step,
228947dc10d7SGordon Ross 		head_list_walk_fini
229047dc10d7SGordon Ross 	},
229147dc10d7SGordon Ross 	{ NULL }
229247dc10d7SGordon Ross };
229347dc10d7SGordon Ross 
229447dc10d7SGordon Ross static const mdb_modinfo_t modinfo = {
229547dc10d7SGordon Ross 	MDB_API_VERSION, dcmds, walkers
229647dc10d7SGordon Ross };
229747dc10d7SGordon Ross 
229847dc10d7SGordon Ross const mdb_modinfo_t *
_mdb_init(void)229947dc10d7SGordon Ross _mdb_init(void)
230047dc10d7SGordon Ross {
230147dc10d7SGordon Ross 	return (&modinfo);
230247dc10d7SGordon Ross }
2303