xref: /onnv-gate/usr/src/cmd/mdb/common/modules/genunix/irm.c (revision 8561:14b63022c7d9)
1*8561SScott.Carter@Sun.COM /*
2*8561SScott.Carter@Sun.COM  * CDDL HEADER START
3*8561SScott.Carter@Sun.COM  *
4*8561SScott.Carter@Sun.COM  * The contents of this file are subject to the terms of the
5*8561SScott.Carter@Sun.COM  * Common Development and Distribution License (the "License").
6*8561SScott.Carter@Sun.COM  * You may not use this file except in compliance with the License.
7*8561SScott.Carter@Sun.COM  *
8*8561SScott.Carter@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*8561SScott.Carter@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*8561SScott.Carter@Sun.COM  * See the License for the specific language governing permissions
11*8561SScott.Carter@Sun.COM  * and limitations under the License.
12*8561SScott.Carter@Sun.COM  *
13*8561SScott.Carter@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*8561SScott.Carter@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*8561SScott.Carter@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*8561SScott.Carter@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*8561SScott.Carter@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*8561SScott.Carter@Sun.COM  *
19*8561SScott.Carter@Sun.COM  * CDDL HEADER END
20*8561SScott.Carter@Sun.COM  */
21*8561SScott.Carter@Sun.COM /*
22*8561SScott.Carter@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*8561SScott.Carter@Sun.COM  * Use is subject to license terms.
24*8561SScott.Carter@Sun.COM  */
25*8561SScott.Carter@Sun.COM 
26*8561SScott.Carter@Sun.COM #include <sys/mdb_modapi.h>
27*8561SScott.Carter@Sun.COM #include <sys/proc.h>
28*8561SScott.Carter@Sun.COM #include <sys/types.h>
29*8561SScott.Carter@Sun.COM #include <sys/sunddi.h>
30*8561SScott.Carter@Sun.COM #include <sys/ddi_intr.h>
31*8561SScott.Carter@Sun.COM #include <sys/ddi_intr_impl.h>
32*8561SScott.Carter@Sun.COM #include <stddef.h>
33*8561SScott.Carter@Sun.COM 
34*8561SScott.Carter@Sun.COM #include "list.h"
35*8561SScott.Carter@Sun.COM 
36*8561SScott.Carter@Sun.COM extern int	mdb_devinfo2driver(uintptr_t, char *, size_t);
37*8561SScott.Carter@Sun.COM 
38*8561SScott.Carter@Sun.COM static char *
39*8561SScott.Carter@Sun.COM irm_get_type(int type)
40*8561SScott.Carter@Sun.COM {
41*8561SScott.Carter@Sun.COM 	if (type == (DDI_INTR_TYPE_MSI | DDI_INTR_TYPE_MSIX))
42*8561SScott.Carter@Sun.COM 		return ("MSI/X");
43*8561SScott.Carter@Sun.COM 
44*8561SScott.Carter@Sun.COM 	switch (type) {
45*8561SScott.Carter@Sun.COM 	case DDI_INTR_TYPE_FIXED:
46*8561SScott.Carter@Sun.COM 		return ("Fixed");
47*8561SScott.Carter@Sun.COM 	case DDI_INTR_TYPE_MSI:
48*8561SScott.Carter@Sun.COM 		return ("MSI");
49*8561SScott.Carter@Sun.COM 	case DDI_INTR_TYPE_MSIX:
50*8561SScott.Carter@Sun.COM 		return ("MSI-X");
51*8561SScott.Carter@Sun.COM 	default:
52*8561SScott.Carter@Sun.COM 		return ("Unknown");
53*8561SScott.Carter@Sun.COM 	}
54*8561SScott.Carter@Sun.COM }
55*8561SScott.Carter@Sun.COM 
56*8561SScott.Carter@Sun.COM int
57*8561SScott.Carter@Sun.COM irmpools_walk_init(mdb_walk_state_t *wsp)
58*8561SScott.Carter@Sun.COM {
59*8561SScott.Carter@Sun.COM 	GElf_Sym sym;
60*8561SScott.Carter@Sun.COM 
61*8561SScott.Carter@Sun.COM 	if (mdb_lookup_by_name("irm_pools_list", &sym) == -1) {
62*8561SScott.Carter@Sun.COM 		mdb_warn("couldn't find irm_pools_list");
63*8561SScott.Carter@Sun.COM 		return (WALK_ERR);
64*8561SScott.Carter@Sun.COM 	}
65*8561SScott.Carter@Sun.COM 
66*8561SScott.Carter@Sun.COM 	wsp->walk_addr = (uintptr_t)sym.st_value;
67*8561SScott.Carter@Sun.COM 
68*8561SScott.Carter@Sun.COM 	return (list_walk_init_named(wsp, "interrupt pools", "pool"));
69*8561SScott.Carter@Sun.COM }
70*8561SScott.Carter@Sun.COM 
71*8561SScott.Carter@Sun.COM int
72*8561SScott.Carter@Sun.COM irmreqs_walk_init(mdb_walk_state_t *wsp)
73*8561SScott.Carter@Sun.COM {
74*8561SScott.Carter@Sun.COM 	wsp->walk_addr = (uintptr_t)(wsp->walk_addr +
75*8561SScott.Carter@Sun.COM 	    offsetof(ddi_irm_pool_t, ipool_req_list));
76*8561SScott.Carter@Sun.COM 
77*8561SScott.Carter@Sun.COM 	return (list_walk_init_named(wsp, "interrupt requests", "request"));
78*8561SScott.Carter@Sun.COM }
79*8561SScott.Carter@Sun.COM 
80*8561SScott.Carter@Sun.COM int
81*8561SScott.Carter@Sun.COM irmpools_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
82*8561SScott.Carter@Sun.COM {
83*8561SScott.Carter@Sun.COM 	ddi_irm_pool_t	pool;
84*8561SScott.Carter@Sun.COM 	struct dev_info	dev;
85*8561SScott.Carter@Sun.COM 	char		driver[MODMAXNAMELEN + 1] = "";
86*8561SScott.Carter@Sun.COM 	char		devname[MODMAXNAMELEN + 1] = "";
87*8561SScott.Carter@Sun.COM 
88*8561SScott.Carter@Sun.COM 	if (argc != 0)
89*8561SScott.Carter@Sun.COM 		return (DCMD_USAGE);
90*8561SScott.Carter@Sun.COM 
91*8561SScott.Carter@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
92*8561SScott.Carter@Sun.COM 		if (mdb_walk_dcmd("irmpools", "irmpools", argc, argv) == -1) {
93*8561SScott.Carter@Sun.COM 			mdb_warn("can't walk interrupt pools");
94*8561SScott.Carter@Sun.COM 			return (DCMD_ERR);
95*8561SScott.Carter@Sun.COM 		}
96*8561SScott.Carter@Sun.COM 		return (DCMD_OK);
97*8561SScott.Carter@Sun.COM 	}
98*8561SScott.Carter@Sun.COM 
99*8561SScott.Carter@Sun.COM 	if (DCMD_HDRSPEC(flags)) {
100*8561SScott.Carter@Sun.COM 		mdb_printf("%<u>%?s  %-18s  %-8s  %-6s  %-9s  %-8s%</u>\n",
101*8561SScott.Carter@Sun.COM 		    "ADDR", "OWNER", "TYPE", "SIZE", "REQUESTED", "RESERVED");
102*8561SScott.Carter@Sun.COM 	}
103*8561SScott.Carter@Sun.COM 
104*8561SScott.Carter@Sun.COM 	if (mdb_vread(&pool, sizeof (pool), addr) != sizeof (pool)) {
105*8561SScott.Carter@Sun.COM 		mdb_warn("couldn't read interrupt pool at %p", addr);
106*8561SScott.Carter@Sun.COM 		return (DCMD_ERR);
107*8561SScott.Carter@Sun.COM 	}
108*8561SScott.Carter@Sun.COM 
109*8561SScott.Carter@Sun.COM 	if (mdb_vread(&dev, sizeof (dev),
110*8561SScott.Carter@Sun.COM 	    (uintptr_t)pool.ipool_owner) != sizeof (dev)) {
111*8561SScott.Carter@Sun.COM 		mdb_warn("couldn't read dev_info at %p", pool.ipool_owner);
112*8561SScott.Carter@Sun.COM 		return (DCMD_ERR);
113*8561SScott.Carter@Sun.COM 	}
114*8561SScott.Carter@Sun.COM 
115*8561SScott.Carter@Sun.COM 	mdb_devinfo2driver((uintptr_t)pool.ipool_owner, driver,
116*8561SScott.Carter@Sun.COM 	    sizeof (driver));
117*8561SScott.Carter@Sun.COM 	mdb_snprintf(devname, sizeof (devname), "%s#%d", driver,
118*8561SScott.Carter@Sun.COM 	    dev.devi_instance);
119*8561SScott.Carter@Sun.COM 
120*8561SScott.Carter@Sun.COM 	mdb_printf("%0?p  %-18s  %-8s  %-6d  %-9d  %-8d\n", addr, devname,
121*8561SScott.Carter@Sun.COM 	    irm_get_type(pool.ipool_types), pool.ipool_totsz,
122*8561SScott.Carter@Sun.COM 	    pool.ipool_reqno, pool.ipool_resno);
123*8561SScott.Carter@Sun.COM 
124*8561SScott.Carter@Sun.COM 	return (DCMD_OK);
125*8561SScott.Carter@Sun.COM }
126*8561SScott.Carter@Sun.COM 
127*8561SScott.Carter@Sun.COM int
128*8561SScott.Carter@Sun.COM irmreqs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
129*8561SScott.Carter@Sun.COM {
130*8561SScott.Carter@Sun.COM 	if (argc != 0)
131*8561SScott.Carter@Sun.COM 		return (DCMD_USAGE);
132*8561SScott.Carter@Sun.COM 
133*8561SScott.Carter@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
134*8561SScott.Carter@Sun.COM 		mdb_warn("can't perform global interrupt request walk");
135*8561SScott.Carter@Sun.COM 		return (DCMD_ERR);
136*8561SScott.Carter@Sun.COM 	}
137*8561SScott.Carter@Sun.COM 
138*8561SScott.Carter@Sun.COM 	if (mdb_pwalk_dcmd("irmreqs", "irmreq", argc, argv, addr) == -1) {
139*8561SScott.Carter@Sun.COM 		mdb_warn("can't walk interrupt requests");
140*8561SScott.Carter@Sun.COM 		return (DCMD_ERR);
141*8561SScott.Carter@Sun.COM 	}
142*8561SScott.Carter@Sun.COM 
143*8561SScott.Carter@Sun.COM 	return (DCMD_OK);
144*8561SScott.Carter@Sun.COM }
145*8561SScott.Carter@Sun.COM 
146*8561SScott.Carter@Sun.COM /*ARGSUSED*/
147*8561SScott.Carter@Sun.COM int
148*8561SScott.Carter@Sun.COM irmreq_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
149*8561SScott.Carter@Sun.COM {
150*8561SScott.Carter@Sun.COM 	ddi_irm_req_t		req;
151*8561SScott.Carter@Sun.COM 	struct dev_info		dev;
152*8561SScott.Carter@Sun.COM 	struct devinfo_intr	intr;
153*8561SScott.Carter@Sun.COM 	char			driver[MODMAXNAMELEN + 1] = "";
154*8561SScott.Carter@Sun.COM 	char			devname[MODMAXNAMELEN + 1] = "";
155*8561SScott.Carter@Sun.COM 
156*8561SScott.Carter@Sun.COM 	if (argc != 0)
157*8561SScott.Carter@Sun.COM 		return (DCMD_USAGE);
158*8561SScott.Carter@Sun.COM 
159*8561SScott.Carter@Sun.COM 	if (!(flags & DCMD_ADDRSPEC)) {
160*8561SScott.Carter@Sun.COM 		return (DCMD_ERR);
161*8561SScott.Carter@Sun.COM 	}
162*8561SScott.Carter@Sun.COM 
163*8561SScott.Carter@Sun.COM 	if (DCMD_HDRSPEC(flags)) {
164*8561SScott.Carter@Sun.COM 		mdb_printf("%<u>%?s  %-18s  %-8s  %-8s  %-6s  %-4s  "
165*8561SScott.Carter@Sun.COM 		    "%-6s%</u>\n", "ADDR", "OWNER", "TYPE", "CALLBACK",
166*8561SScott.Carter@Sun.COM 		    "NINTRS", "NREQ", "NAVAIL");
167*8561SScott.Carter@Sun.COM 	}
168*8561SScott.Carter@Sun.COM 
169*8561SScott.Carter@Sun.COM 	if (mdb_vread(&req, sizeof (req), addr) != sizeof (req)) {
170*8561SScott.Carter@Sun.COM 		mdb_warn("couldn't read interrupt request at %p", addr);
171*8561SScott.Carter@Sun.COM 		return (DCMD_ERR);
172*8561SScott.Carter@Sun.COM 	}
173*8561SScott.Carter@Sun.COM 
174*8561SScott.Carter@Sun.COM 	if (mdb_vread(&dev, sizeof (dev),
175*8561SScott.Carter@Sun.COM 	    (uintptr_t)req.ireq_dip) != sizeof (dev)) {
176*8561SScott.Carter@Sun.COM 		mdb_warn("couldn't read dev_info at %p", req.ireq_dip);
177*8561SScott.Carter@Sun.COM 		return (DCMD_ERR);
178*8561SScott.Carter@Sun.COM 	}
179*8561SScott.Carter@Sun.COM 
180*8561SScott.Carter@Sun.COM 	if (mdb_vread(&intr, sizeof (intr),
181*8561SScott.Carter@Sun.COM 	    (uintptr_t)dev.devi_intr_p) != sizeof (intr)) {
182*8561SScott.Carter@Sun.COM 		mdb_warn("couldn't read devinfo_intr at %p", dev.devi_intr_p);
183*8561SScott.Carter@Sun.COM 		return (DCMD_ERR);
184*8561SScott.Carter@Sun.COM 	}
185*8561SScott.Carter@Sun.COM 
186*8561SScott.Carter@Sun.COM 	mdb_devinfo2driver((uintptr_t)req.ireq_dip, driver, sizeof (driver));
187*8561SScott.Carter@Sun.COM 	mdb_snprintf(devname, sizeof (devname), "%s#%d", driver,
188*8561SScott.Carter@Sun.COM 	    dev.devi_instance);
189*8561SScott.Carter@Sun.COM 
190*8561SScott.Carter@Sun.COM 	mdb_printf("%0?p  %-18s  %-8s  %-8s  %-6d  %-4d  %-6d\n",
191*8561SScott.Carter@Sun.COM 	    addr, devname, irm_get_type(req.ireq_type),
192*8561SScott.Carter@Sun.COM 	    (req.ireq_flags & DDI_IRM_FLAG_CALLBACK) ? "Yes" : "No",
193*8561SScott.Carter@Sun.COM 	    intr.devi_intr_sup_nintrs, req.ireq_nreq, req.ireq_navail);
194*8561SScott.Carter@Sun.COM 
195*8561SScott.Carter@Sun.COM 	return (DCMD_OK);
196*8561SScott.Carter@Sun.COM }
197