18561SScott.Carter@Sun.COM /* 28561SScott.Carter@Sun.COM * CDDL HEADER START 38561SScott.Carter@Sun.COM * 48561SScott.Carter@Sun.COM * The contents of this file are subject to the terms of the 58561SScott.Carter@Sun.COM * Common Development and Distribution License (the "License"). 68561SScott.Carter@Sun.COM * You may not use this file except in compliance with the License. 78561SScott.Carter@Sun.COM * 88561SScott.Carter@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 98561SScott.Carter@Sun.COM * or http://www.opensolaris.org/os/licensing. 108561SScott.Carter@Sun.COM * See the License for the specific language governing permissions 118561SScott.Carter@Sun.COM * and limitations under the License. 128561SScott.Carter@Sun.COM * 138561SScott.Carter@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 148561SScott.Carter@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 158561SScott.Carter@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 168561SScott.Carter@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 178561SScott.Carter@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 188561SScott.Carter@Sun.COM * 198561SScott.Carter@Sun.COM * CDDL HEADER END 208561SScott.Carter@Sun.COM */ 218561SScott.Carter@Sun.COM /* 2212652SScott.Carter@Oracle.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 238561SScott.Carter@Sun.COM */ 248561SScott.Carter@Sun.COM 258561SScott.Carter@Sun.COM #include <sys/mdb_modapi.h> 268561SScott.Carter@Sun.COM #include <sys/proc.h> 278561SScott.Carter@Sun.COM #include <sys/types.h> 288561SScott.Carter@Sun.COM #include <sys/sunddi.h> 298561SScott.Carter@Sun.COM #include <sys/ddi_intr.h> 308561SScott.Carter@Sun.COM #include <sys/ddi_intr_impl.h> 318561SScott.Carter@Sun.COM #include <stddef.h> 328561SScott.Carter@Sun.COM 338561SScott.Carter@Sun.COM #include "list.h" 348561SScott.Carter@Sun.COM 358561SScott.Carter@Sun.COM extern int mdb_devinfo2driver(uintptr_t, char *, size_t); 368561SScott.Carter@Sun.COM 378561SScott.Carter@Sun.COM static char * 388561SScott.Carter@Sun.COM irm_get_type(int type) 398561SScott.Carter@Sun.COM { 408561SScott.Carter@Sun.COM if (type == (DDI_INTR_TYPE_MSI | DDI_INTR_TYPE_MSIX)) 418561SScott.Carter@Sun.COM return ("MSI/X"); 428561SScott.Carter@Sun.COM 438561SScott.Carter@Sun.COM switch (type) { 448561SScott.Carter@Sun.COM case DDI_INTR_TYPE_FIXED: 458561SScott.Carter@Sun.COM return ("Fixed"); 468561SScott.Carter@Sun.COM case DDI_INTR_TYPE_MSI: 478561SScott.Carter@Sun.COM return ("MSI"); 488561SScott.Carter@Sun.COM case DDI_INTR_TYPE_MSIX: 498561SScott.Carter@Sun.COM return ("MSI-X"); 508561SScott.Carter@Sun.COM default: 518561SScott.Carter@Sun.COM return ("Unknown"); 528561SScott.Carter@Sun.COM } 538561SScott.Carter@Sun.COM } 548561SScott.Carter@Sun.COM 5512652SScott.Carter@Oracle.COM static int 5612652SScott.Carter@Oracle.COM check_irm_enabled(void) 5712652SScott.Carter@Oracle.COM { 5812652SScott.Carter@Oracle.COM GElf_Sym sym; 5912652SScott.Carter@Oracle.COM uintptr_t addr; 6012652SScott.Carter@Oracle.COM int value; 6112652SScott.Carter@Oracle.COM 6212652SScott.Carter@Oracle.COM if (mdb_lookup_by_name("irm_enable", &sym) == -1) { 6312652SScott.Carter@Oracle.COM mdb_warn("couldn't find irm_enable"); 6412652SScott.Carter@Oracle.COM return (0); 6512652SScott.Carter@Oracle.COM } 6612652SScott.Carter@Oracle.COM 6712652SScott.Carter@Oracle.COM addr = (uintptr_t)sym.st_value; 6812652SScott.Carter@Oracle.COM 6912652SScott.Carter@Oracle.COM if (mdb_vread(&value, sizeof (value), addr) != sizeof (value)) { 7012652SScott.Carter@Oracle.COM mdb_warn("couldn't read irm_enable at %p", addr); 7112652SScott.Carter@Oracle.COM return (0); 7212652SScott.Carter@Oracle.COM } 7312652SScott.Carter@Oracle.COM 7412652SScott.Carter@Oracle.COM return (value); 7512652SScott.Carter@Oracle.COM } 7612652SScott.Carter@Oracle.COM 778561SScott.Carter@Sun.COM int 788561SScott.Carter@Sun.COM irmpools_walk_init(mdb_walk_state_t *wsp) 798561SScott.Carter@Sun.COM { 808561SScott.Carter@Sun.COM GElf_Sym sym; 818561SScott.Carter@Sun.COM 828561SScott.Carter@Sun.COM if (mdb_lookup_by_name("irm_pools_list", &sym) == -1) { 838561SScott.Carter@Sun.COM mdb_warn("couldn't find irm_pools_list"); 848561SScott.Carter@Sun.COM return (WALK_ERR); 858561SScott.Carter@Sun.COM } 868561SScott.Carter@Sun.COM 878561SScott.Carter@Sun.COM wsp->walk_addr = (uintptr_t)sym.st_value; 888561SScott.Carter@Sun.COM 898561SScott.Carter@Sun.COM return (list_walk_init_named(wsp, "interrupt pools", "pool")); 908561SScott.Carter@Sun.COM } 918561SScott.Carter@Sun.COM 928561SScott.Carter@Sun.COM int 938561SScott.Carter@Sun.COM irmreqs_walk_init(mdb_walk_state_t *wsp) 948561SScott.Carter@Sun.COM { 958561SScott.Carter@Sun.COM wsp->walk_addr = (uintptr_t)(wsp->walk_addr + 968561SScott.Carter@Sun.COM offsetof(ddi_irm_pool_t, ipool_req_list)); 978561SScott.Carter@Sun.COM 988561SScott.Carter@Sun.COM return (list_walk_init_named(wsp, "interrupt requests", "request")); 998561SScott.Carter@Sun.COM } 1008561SScott.Carter@Sun.COM 1018561SScott.Carter@Sun.COM int 1028561SScott.Carter@Sun.COM irmpools_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1038561SScott.Carter@Sun.COM { 1048561SScott.Carter@Sun.COM ddi_irm_pool_t pool; 1058561SScott.Carter@Sun.COM struct dev_info dev; 1068561SScott.Carter@Sun.COM char driver[MODMAXNAMELEN + 1] = ""; 1078561SScott.Carter@Sun.COM char devname[MODMAXNAMELEN + 1] = ""; 1088561SScott.Carter@Sun.COM 1098561SScott.Carter@Sun.COM if (argc != 0) 1108561SScott.Carter@Sun.COM return (DCMD_USAGE); 1118561SScott.Carter@Sun.COM 11212652SScott.Carter@Oracle.COM if (check_irm_enabled() == 0) { 11312652SScott.Carter@Oracle.COM mdb_warn("IRM is not enabled"); 11412652SScott.Carter@Oracle.COM return (DCMD_ERR); 11512652SScott.Carter@Oracle.COM } 11612652SScott.Carter@Oracle.COM 1178561SScott.Carter@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 1188561SScott.Carter@Sun.COM if (mdb_walk_dcmd("irmpools", "irmpools", argc, argv) == -1) { 1198561SScott.Carter@Sun.COM mdb_warn("can't walk interrupt pools"); 1208561SScott.Carter@Sun.COM return (DCMD_ERR); 1218561SScott.Carter@Sun.COM } 1228561SScott.Carter@Sun.COM return (DCMD_OK); 1238561SScott.Carter@Sun.COM } 1248561SScott.Carter@Sun.COM 1258561SScott.Carter@Sun.COM if (DCMD_HDRSPEC(flags)) { 1268561SScott.Carter@Sun.COM mdb_printf("%<u>%?s %-18s %-8s %-6s %-9s %-8s%</u>\n", 1278561SScott.Carter@Sun.COM "ADDR", "OWNER", "TYPE", "SIZE", "REQUESTED", "RESERVED"); 1288561SScott.Carter@Sun.COM } 1298561SScott.Carter@Sun.COM 1308561SScott.Carter@Sun.COM if (mdb_vread(&pool, sizeof (pool), addr) != sizeof (pool)) { 1318561SScott.Carter@Sun.COM mdb_warn("couldn't read interrupt pool at %p", addr); 1328561SScott.Carter@Sun.COM return (DCMD_ERR); 1338561SScott.Carter@Sun.COM } 1348561SScott.Carter@Sun.COM 1358561SScott.Carter@Sun.COM if (mdb_vread(&dev, sizeof (dev), 1368561SScott.Carter@Sun.COM (uintptr_t)pool.ipool_owner) != sizeof (dev)) { 1378561SScott.Carter@Sun.COM mdb_warn("couldn't read dev_info at %p", pool.ipool_owner); 1388561SScott.Carter@Sun.COM return (DCMD_ERR); 1398561SScott.Carter@Sun.COM } 1408561SScott.Carter@Sun.COM 1418561SScott.Carter@Sun.COM mdb_devinfo2driver((uintptr_t)pool.ipool_owner, driver, 1428561SScott.Carter@Sun.COM sizeof (driver)); 143*12683SJimmy.Vetayases@oracle.com /* 144*12683SJimmy.Vetayases@oracle.com * Include driver instance number only if the node has an 145*12683SJimmy.Vetayases@oracle.com * instance number assigned (i.e. instance != -1) to it. 146*12683SJimmy.Vetayases@oracle.com * This will cover cases like rootnex driver which doesn't 147*12683SJimmy.Vetayases@oracle.com * have instance number assigned to it. 148*12683SJimmy.Vetayases@oracle.com */ 149*12683SJimmy.Vetayases@oracle.com if (dev.devi_instance != -1) 150*12683SJimmy.Vetayases@oracle.com mdb_snprintf(devname, sizeof (devname), "%s#%d", driver, 151*12683SJimmy.Vetayases@oracle.com dev.devi_instance); 152*12683SJimmy.Vetayases@oracle.com else 153*12683SJimmy.Vetayases@oracle.com mdb_snprintf(devname, sizeof (devname), "%s", driver); 1548561SScott.Carter@Sun.COM 1558561SScott.Carter@Sun.COM mdb_printf("%0?p %-18s %-8s %-6d %-9d %-8d\n", addr, devname, 1568561SScott.Carter@Sun.COM irm_get_type(pool.ipool_types), pool.ipool_totsz, 1578561SScott.Carter@Sun.COM pool.ipool_reqno, pool.ipool_resno); 1588561SScott.Carter@Sun.COM 1598561SScott.Carter@Sun.COM return (DCMD_OK); 1608561SScott.Carter@Sun.COM } 1618561SScott.Carter@Sun.COM 1628561SScott.Carter@Sun.COM int 1638561SScott.Carter@Sun.COM irmreqs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1648561SScott.Carter@Sun.COM { 1658561SScott.Carter@Sun.COM if (argc != 0) 1668561SScott.Carter@Sun.COM return (DCMD_USAGE); 1678561SScott.Carter@Sun.COM 16812652SScott.Carter@Oracle.COM if (check_irm_enabled() == 0) { 16912652SScott.Carter@Oracle.COM mdb_warn("IRM is not enabled"); 17012652SScott.Carter@Oracle.COM return (DCMD_ERR); 17112652SScott.Carter@Oracle.COM } 17212652SScott.Carter@Oracle.COM 1738561SScott.Carter@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 1748561SScott.Carter@Sun.COM mdb_warn("can't perform global interrupt request walk"); 1758561SScott.Carter@Sun.COM return (DCMD_ERR); 1768561SScott.Carter@Sun.COM } 1778561SScott.Carter@Sun.COM 1788561SScott.Carter@Sun.COM if (mdb_pwalk_dcmd("irmreqs", "irmreq", argc, argv, addr) == -1) { 1798561SScott.Carter@Sun.COM mdb_warn("can't walk interrupt requests"); 1808561SScott.Carter@Sun.COM return (DCMD_ERR); 1818561SScott.Carter@Sun.COM } 1828561SScott.Carter@Sun.COM 1838561SScott.Carter@Sun.COM return (DCMD_OK); 1848561SScott.Carter@Sun.COM } 1858561SScott.Carter@Sun.COM 1868561SScott.Carter@Sun.COM /*ARGSUSED*/ 1878561SScott.Carter@Sun.COM int 1888561SScott.Carter@Sun.COM irmreq_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1898561SScott.Carter@Sun.COM { 1908561SScott.Carter@Sun.COM ddi_irm_req_t req; 1918561SScott.Carter@Sun.COM struct dev_info dev; 1928561SScott.Carter@Sun.COM struct devinfo_intr intr; 1938561SScott.Carter@Sun.COM char driver[MODMAXNAMELEN + 1] = ""; 1948561SScott.Carter@Sun.COM char devname[MODMAXNAMELEN + 1] = ""; 1958561SScott.Carter@Sun.COM 1968561SScott.Carter@Sun.COM if (argc != 0) 1978561SScott.Carter@Sun.COM return (DCMD_USAGE); 1988561SScott.Carter@Sun.COM 1998561SScott.Carter@Sun.COM if (!(flags & DCMD_ADDRSPEC)) { 2008561SScott.Carter@Sun.COM return (DCMD_ERR); 2018561SScott.Carter@Sun.COM } 2028561SScott.Carter@Sun.COM 2038561SScott.Carter@Sun.COM if (DCMD_HDRSPEC(flags)) { 2048561SScott.Carter@Sun.COM mdb_printf("%<u>%?s %-18s %-8s %-8s %-6s %-4s " 2058561SScott.Carter@Sun.COM "%-6s%</u>\n", "ADDR", "OWNER", "TYPE", "CALLBACK", 2068561SScott.Carter@Sun.COM "NINTRS", "NREQ", "NAVAIL"); 2078561SScott.Carter@Sun.COM } 2088561SScott.Carter@Sun.COM 2098561SScott.Carter@Sun.COM if (mdb_vread(&req, sizeof (req), addr) != sizeof (req)) { 2108561SScott.Carter@Sun.COM mdb_warn("couldn't read interrupt request at %p", addr); 2118561SScott.Carter@Sun.COM return (DCMD_ERR); 2128561SScott.Carter@Sun.COM } 2138561SScott.Carter@Sun.COM 2148561SScott.Carter@Sun.COM if (mdb_vread(&dev, sizeof (dev), 2158561SScott.Carter@Sun.COM (uintptr_t)req.ireq_dip) != sizeof (dev)) { 2168561SScott.Carter@Sun.COM mdb_warn("couldn't read dev_info at %p", req.ireq_dip); 2178561SScott.Carter@Sun.COM return (DCMD_ERR); 2188561SScott.Carter@Sun.COM } 2198561SScott.Carter@Sun.COM 2208561SScott.Carter@Sun.COM if (mdb_vread(&intr, sizeof (intr), 2218561SScott.Carter@Sun.COM (uintptr_t)dev.devi_intr_p) != sizeof (intr)) { 2228561SScott.Carter@Sun.COM mdb_warn("couldn't read devinfo_intr at %p", dev.devi_intr_p); 2238561SScott.Carter@Sun.COM return (DCMD_ERR); 2248561SScott.Carter@Sun.COM } 2258561SScott.Carter@Sun.COM 2268561SScott.Carter@Sun.COM mdb_devinfo2driver((uintptr_t)req.ireq_dip, driver, sizeof (driver)); 2278561SScott.Carter@Sun.COM mdb_snprintf(devname, sizeof (devname), "%s#%d", driver, 2288561SScott.Carter@Sun.COM dev.devi_instance); 2298561SScott.Carter@Sun.COM 2308561SScott.Carter@Sun.COM mdb_printf("%0?p %-18s %-8s %-8s %-6d %-4d %-6d\n", 2318561SScott.Carter@Sun.COM addr, devname, irm_get_type(req.ireq_type), 2328561SScott.Carter@Sun.COM (req.ireq_flags & DDI_IRM_FLAG_CALLBACK) ? "Yes" : "No", 2338561SScott.Carter@Sun.COM intr.devi_intr_sup_nintrs, req.ireq_nreq, req.ireq_navail); 2348561SScott.Carter@Sun.COM 2358561SScott.Carter@Sun.COM return (DCMD_OK); 2368561SScott.Carter@Sun.COM } 237