4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <sys/mdb_modapi.h>
27 #include <sys/types.h>
28 #include <sys/sunddi.h>
29 #include <sys/ddi_intr.h>
30 #include <sys/ddi_intr_impl.h>
35 extern int mdb_devinfo2driver(uintptr_t, char *, size_t);
38 irm_get_type(int type
)
40 if (type
== (DDI_INTR_TYPE_MSI
| DDI_INTR_TYPE_MSIX
))
44 case DDI_INTR_TYPE_FIXED
:
46 case DDI_INTR_TYPE_MSI
:
48 case DDI_INTR_TYPE_MSIX
:
56 check_irm_enabled(void)
62 if (mdb_lookup_by_name("irm_enable", &sym
) == -1) {
63 mdb_warn("couldn't find irm_enable");
67 addr
= (uintptr_t)sym
.st_value
;
69 if (mdb_vread(&value
, sizeof (value
), addr
) != sizeof (value
)) {
70 mdb_warn("couldn't read irm_enable at %p", addr
);
78 irmpools_walk_init(mdb_walk_state_t
*wsp
)
82 if (mdb_lookup_by_name("irm_pools_list", &sym
) == -1) {
83 mdb_warn("couldn't find irm_pools_list");
87 wsp
->walk_addr
= (uintptr_t)sym
.st_value
;
89 return (list_walk_init_named(wsp
, "interrupt pools", "pool"));
93 irmreqs_walk_init(mdb_walk_state_t
*wsp
)
95 wsp
->walk_addr
= (uintptr_t)(wsp
->walk_addr
+
96 offsetof(ddi_irm_pool_t
, ipool_req_list
));
98 return (list_walk_init_named(wsp
, "interrupt requests", "request"));
102 irmpools_dcmd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
106 char driver
[MODMAXNAMELEN
+ 1] = "";
107 char devname
[MODMAXNAMELEN
+ 1] = "";
112 if (check_irm_enabled() == 0) {
113 mdb_warn("IRM is not enabled");
117 if (!(flags
& DCMD_ADDRSPEC
)) {
118 if (mdb_walk_dcmd("irmpools", "irmpools", argc
, argv
) == -1) {
119 mdb_warn("can't walk interrupt pools");
125 if (DCMD_HDRSPEC(flags
)) {
126 mdb_printf("%<u>%?s %-18s %-8s %-6s %-9s %-8s%</u>\n",
127 "ADDR", "OWNER", "TYPE", "SIZE", "REQUESTED", "RESERVED");
130 if (mdb_vread(&pool
, sizeof (pool
), addr
) != sizeof (pool
)) {
131 mdb_warn("couldn't read interrupt pool at %p", addr
);
135 if (mdb_vread(&dev
, sizeof (dev
),
136 (uintptr_t)pool
.ipool_owner
) != sizeof (dev
)) {
137 mdb_warn("couldn't read dev_info at %p", pool
.ipool_owner
);
141 mdb_devinfo2driver((uintptr_t)pool
.ipool_owner
, driver
,
144 * Include driver instance number only if the node has an
145 * instance number assigned (i.e. instance != -1) to it.
146 * This will cover cases like rootnex driver which doesn't
147 * have instance number assigned to it.
149 if (dev
.devi_instance
!= -1)
150 mdb_snprintf(devname
, sizeof (devname
), "%s#%d", driver
,
153 mdb_snprintf(devname
, sizeof (devname
), "%s", driver
);
155 mdb_printf("%0?p %-18s %-8s %-6d %-9d %-8d\n", addr
, devname
,
156 irm_get_type(pool
.ipool_types
), pool
.ipool_totsz
,
157 pool
.ipool_reqno
, pool
.ipool_resno
);
163 irmreqs_dcmd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
168 if (check_irm_enabled() == 0) {
169 mdb_warn("IRM is not enabled");
173 if (!(flags
& DCMD_ADDRSPEC
)) {
174 mdb_warn("can't perform global interrupt request walk");
178 if (mdb_pwalk_dcmd("irmreqs", "irmreq", argc
, argv
, addr
) == -1) {
179 mdb_warn("can't walk interrupt requests");
188 irmreq_dcmd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
192 struct devinfo_intr intr
;
193 char driver
[MODMAXNAMELEN
+ 1] = "";
194 char devname
[MODMAXNAMELEN
+ 1] = "";
199 if (!(flags
& DCMD_ADDRSPEC
)) {
203 if (DCMD_HDRSPEC(flags
)) {
204 mdb_printf("%<u>%?s %-18s %-8s %-8s %-6s %-4s "
205 "%-6s%</u>\n", "ADDR", "OWNER", "TYPE", "CALLBACK",
206 "NINTRS", "NREQ", "NAVAIL");
209 if (mdb_vread(&req
, sizeof (req
), addr
) != sizeof (req
)) {
210 mdb_warn("couldn't read interrupt request at %p", addr
);
214 if (mdb_vread(&dev
, sizeof (dev
),
215 (uintptr_t)req
.ireq_dip
) != sizeof (dev
)) {
216 mdb_warn("couldn't read dev_info at %p", req
.ireq_dip
);
220 if (mdb_vread(&intr
, sizeof (intr
),
221 (uintptr_t)dev
.devi_intr_p
) != sizeof (intr
)) {
222 mdb_warn("couldn't read devinfo_intr at %p", dev
.devi_intr_p
);
226 mdb_devinfo2driver((uintptr_t)req
.ireq_dip
, driver
, sizeof (driver
));
227 mdb_snprintf(devname
, sizeof (devname
), "%s#%d", driver
,
230 mdb_printf("%0?p %-18s %-8s %-8s %-6d %-4d %-6d\n",
231 addr
, devname
, irm_get_type(req
.ireq_type
),
232 (req
.ireq_flags
& DDI_IRM_FLAG_CALLBACK
) ? "Yes" : "No",
233 intr
.devi_intr_sup_nintrs
, req
.ireq_nreq
, req
.ireq_navail
);