15febcb4aSScott Carter, SD IOSW /* 25febcb4aSScott Carter, SD IOSW * CDDL HEADER START 35febcb4aSScott Carter, SD IOSW * 45febcb4aSScott Carter, SD IOSW * The contents of this file are subject to the terms of the 55febcb4aSScott Carter, SD IOSW * Common Development and Distribution License (the "License"). 65febcb4aSScott Carter, SD IOSW * You may not use this file except in compliance with the License. 75febcb4aSScott Carter, SD IOSW * 85febcb4aSScott Carter, SD IOSW * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95febcb4aSScott Carter, SD IOSW * or http://www.opensolaris.org/os/licensing. 105febcb4aSScott Carter, SD IOSW * See the License for the specific language governing permissions 115febcb4aSScott Carter, SD IOSW * and limitations under the License. 125febcb4aSScott Carter, SD IOSW * 135febcb4aSScott Carter, SD IOSW * When distributing Covered Code, include this CDDL HEADER in each 145febcb4aSScott Carter, SD IOSW * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155febcb4aSScott Carter, SD IOSW * If applicable, add the following below this CDDL HEADER, with the 165febcb4aSScott Carter, SD IOSW * fields enclosed by brackets "[]" replaced with your own identifying 175febcb4aSScott Carter, SD IOSW * information: Portions Copyright [yyyy] [name of copyright owner] 185febcb4aSScott Carter, SD IOSW * 195febcb4aSScott Carter, SD IOSW * CDDL HEADER END 205febcb4aSScott Carter, SD IOSW */ 215febcb4aSScott Carter, SD IOSW /* 22b285fe30SScott M. Carter * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 235febcb4aSScott Carter, SD IOSW */ 245febcb4aSScott Carter, SD IOSW 255febcb4aSScott Carter, SD IOSW #include <sys/mdb_modapi.h> 265febcb4aSScott Carter, SD IOSW #include <sys/proc.h> 275febcb4aSScott Carter, SD IOSW #include <sys/types.h> 285febcb4aSScott Carter, SD IOSW #include <sys/sunddi.h> 295febcb4aSScott Carter, SD IOSW #include <sys/ddi_intr.h> 305febcb4aSScott Carter, SD IOSW #include <sys/ddi_intr_impl.h> 315febcb4aSScott Carter, SD IOSW #include <stddef.h> 325febcb4aSScott Carter, SD IOSW 335febcb4aSScott Carter, SD IOSW #include "list.h" 345febcb4aSScott Carter, SD IOSW 355febcb4aSScott Carter, SD IOSW extern int mdb_devinfo2driver(uintptr_t, char *, size_t); 365febcb4aSScott Carter, SD IOSW 375febcb4aSScott Carter, SD IOSW static char * 385febcb4aSScott Carter, SD IOSW irm_get_type(int type) 395febcb4aSScott Carter, SD IOSW { 405febcb4aSScott Carter, SD IOSW if (type == (DDI_INTR_TYPE_MSI | DDI_INTR_TYPE_MSIX)) 415febcb4aSScott Carter, SD IOSW return ("MSI/X"); 425febcb4aSScott Carter, SD IOSW 435febcb4aSScott Carter, SD IOSW switch (type) { 445febcb4aSScott Carter, SD IOSW case DDI_INTR_TYPE_FIXED: 455febcb4aSScott Carter, SD IOSW return ("Fixed"); 465febcb4aSScott Carter, SD IOSW case DDI_INTR_TYPE_MSI: 475febcb4aSScott Carter, SD IOSW return ("MSI"); 485febcb4aSScott Carter, SD IOSW case DDI_INTR_TYPE_MSIX: 495febcb4aSScott Carter, SD IOSW return ("MSI-X"); 505febcb4aSScott Carter, SD IOSW default: 515febcb4aSScott Carter, SD IOSW return ("Unknown"); 525febcb4aSScott Carter, SD IOSW } 535febcb4aSScott Carter, SD IOSW } 545febcb4aSScott Carter, SD IOSW 55b285fe30SScott M. Carter static int 56b285fe30SScott M. Carter check_irm_enabled(void) 57b285fe30SScott M. Carter { 58b285fe30SScott M. Carter GElf_Sym sym; 59b285fe30SScott M. Carter uintptr_t addr; 60b285fe30SScott M. Carter int value; 61b285fe30SScott M. Carter 62b285fe30SScott M. Carter if (mdb_lookup_by_name("irm_enable", &sym) == -1) { 63b285fe30SScott M. Carter mdb_warn("couldn't find irm_enable"); 64b285fe30SScott M. Carter return (0); 65b285fe30SScott M. Carter } 66b285fe30SScott M. Carter 67b285fe30SScott M. Carter addr = (uintptr_t)sym.st_value; 68b285fe30SScott M. Carter 69b285fe30SScott M. Carter if (mdb_vread(&value, sizeof (value), addr) != sizeof (value)) { 70b285fe30SScott M. Carter mdb_warn("couldn't read irm_enable at %p", addr); 71b285fe30SScott M. Carter return (0); 72b285fe30SScott M. Carter } 73b285fe30SScott M. Carter 74b285fe30SScott M. Carter return (value); 75b285fe30SScott M. Carter } 76b285fe30SScott M. Carter 775febcb4aSScott Carter, SD IOSW int 785febcb4aSScott Carter, SD IOSW irmpools_walk_init(mdb_walk_state_t *wsp) 795febcb4aSScott Carter, SD IOSW { 805febcb4aSScott Carter, SD IOSW GElf_Sym sym; 815febcb4aSScott Carter, SD IOSW 825febcb4aSScott Carter, SD IOSW if (mdb_lookup_by_name("irm_pools_list", &sym) == -1) { 835febcb4aSScott Carter, SD IOSW mdb_warn("couldn't find irm_pools_list"); 845febcb4aSScott Carter, SD IOSW return (WALK_ERR); 855febcb4aSScott Carter, SD IOSW } 865febcb4aSScott Carter, SD IOSW 875febcb4aSScott Carter, SD IOSW wsp->walk_addr = (uintptr_t)sym.st_value; 885febcb4aSScott Carter, SD IOSW 895febcb4aSScott Carter, SD IOSW return (list_walk_init_named(wsp, "interrupt pools", "pool")); 905febcb4aSScott Carter, SD IOSW } 915febcb4aSScott Carter, SD IOSW 925febcb4aSScott Carter, SD IOSW int 935febcb4aSScott Carter, SD IOSW irmreqs_walk_init(mdb_walk_state_t *wsp) 945febcb4aSScott Carter, SD IOSW { 955febcb4aSScott Carter, SD IOSW wsp->walk_addr = (uintptr_t)(wsp->walk_addr + 965febcb4aSScott Carter, SD IOSW offsetof(ddi_irm_pool_t, ipool_req_list)); 975febcb4aSScott Carter, SD IOSW 985febcb4aSScott Carter, SD IOSW return (list_walk_init_named(wsp, "interrupt requests", "request")); 995febcb4aSScott Carter, SD IOSW } 1005febcb4aSScott Carter, SD IOSW 1015febcb4aSScott Carter, SD IOSW int 1025febcb4aSScott Carter, SD IOSW irmpools_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1035febcb4aSScott Carter, SD IOSW { 1045febcb4aSScott Carter, SD IOSW ddi_irm_pool_t pool; 1055febcb4aSScott Carter, SD IOSW struct dev_info dev; 1065febcb4aSScott Carter, SD IOSW char driver[MODMAXNAMELEN + 1] = ""; 1075febcb4aSScott Carter, SD IOSW char devname[MODMAXNAMELEN + 1] = ""; 1085febcb4aSScott Carter, SD IOSW 1095febcb4aSScott Carter, SD IOSW if (argc != 0) 1105febcb4aSScott Carter, SD IOSW return (DCMD_USAGE); 1115febcb4aSScott Carter, SD IOSW 112b285fe30SScott M. Carter if (check_irm_enabled() == 0) { 113b285fe30SScott M. Carter mdb_warn("IRM is not enabled"); 114b285fe30SScott M. Carter return (DCMD_ERR); 115b285fe30SScott M. Carter } 116b285fe30SScott M. Carter 1175febcb4aSScott Carter, SD IOSW if (!(flags & DCMD_ADDRSPEC)) { 1185febcb4aSScott Carter, SD IOSW if (mdb_walk_dcmd("irmpools", "irmpools", argc, argv) == -1) { 1195febcb4aSScott Carter, SD IOSW mdb_warn("can't walk interrupt pools"); 1205febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 1215febcb4aSScott Carter, SD IOSW } 1225febcb4aSScott Carter, SD IOSW return (DCMD_OK); 1235febcb4aSScott Carter, SD IOSW } 1245febcb4aSScott Carter, SD IOSW 1255febcb4aSScott Carter, SD IOSW if (DCMD_HDRSPEC(flags)) { 1265febcb4aSScott Carter, SD IOSW mdb_printf("%<u>%?s %-18s %-8s %-6s %-9s %-8s%</u>\n", 1275febcb4aSScott Carter, SD IOSW "ADDR", "OWNER", "TYPE", "SIZE", "REQUESTED", "RESERVED"); 1285febcb4aSScott Carter, SD IOSW } 1295febcb4aSScott Carter, SD IOSW 1305febcb4aSScott Carter, SD IOSW if (mdb_vread(&pool, sizeof (pool), addr) != sizeof (pool)) { 1315febcb4aSScott Carter, SD IOSW mdb_warn("couldn't read interrupt pool at %p", addr); 1325febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 1335febcb4aSScott Carter, SD IOSW } 1345febcb4aSScott Carter, SD IOSW 1355febcb4aSScott Carter, SD IOSW if (mdb_vread(&dev, sizeof (dev), 1365febcb4aSScott Carter, SD IOSW (uintptr_t)pool.ipool_owner) != sizeof (dev)) { 1375febcb4aSScott Carter, SD IOSW mdb_warn("couldn't read dev_info at %p", pool.ipool_owner); 1385febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 1395febcb4aSScott Carter, SD IOSW } 1405febcb4aSScott Carter, SD IOSW 1415febcb4aSScott Carter, SD IOSW mdb_devinfo2driver((uintptr_t)pool.ipool_owner, driver, 1425febcb4aSScott Carter, SD IOSW sizeof (driver)); 143*7ff178cdSJimmy Vetayases /* 144*7ff178cdSJimmy Vetayases * Include driver instance number only if the node has an 145*7ff178cdSJimmy Vetayases * instance number assigned (i.e. instance != -1) to it. 146*7ff178cdSJimmy Vetayases * This will cover cases like rootnex driver which doesn't 147*7ff178cdSJimmy Vetayases * have instance number assigned to it. 148*7ff178cdSJimmy Vetayases */ 149*7ff178cdSJimmy Vetayases if (dev.devi_instance != -1) 1505febcb4aSScott Carter, SD IOSW mdb_snprintf(devname, sizeof (devname), "%s#%d", driver, 1515febcb4aSScott Carter, SD IOSW dev.devi_instance); 152*7ff178cdSJimmy Vetayases else 153*7ff178cdSJimmy Vetayases mdb_snprintf(devname, sizeof (devname), "%s", driver); 1545febcb4aSScott Carter, SD IOSW 1555febcb4aSScott Carter, SD IOSW mdb_printf("%0?p %-18s %-8s %-6d %-9d %-8d\n", addr, devname, 1565febcb4aSScott Carter, SD IOSW irm_get_type(pool.ipool_types), pool.ipool_totsz, 1575febcb4aSScott Carter, SD IOSW pool.ipool_reqno, pool.ipool_resno); 1585febcb4aSScott Carter, SD IOSW 1595febcb4aSScott Carter, SD IOSW return (DCMD_OK); 1605febcb4aSScott Carter, SD IOSW } 1615febcb4aSScott Carter, SD IOSW 1625febcb4aSScott Carter, SD IOSW int 1635febcb4aSScott Carter, SD IOSW irmreqs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1645febcb4aSScott Carter, SD IOSW { 1655febcb4aSScott Carter, SD IOSW if (argc != 0) 1665febcb4aSScott Carter, SD IOSW return (DCMD_USAGE); 1675febcb4aSScott Carter, SD IOSW 168b285fe30SScott M. Carter if (check_irm_enabled() == 0) { 169b285fe30SScott M. Carter mdb_warn("IRM is not enabled"); 170b285fe30SScott M. Carter return (DCMD_ERR); 171b285fe30SScott M. Carter } 172b285fe30SScott M. Carter 1735febcb4aSScott Carter, SD IOSW if (!(flags & DCMD_ADDRSPEC)) { 1745febcb4aSScott Carter, SD IOSW mdb_warn("can't perform global interrupt request walk"); 1755febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 1765febcb4aSScott Carter, SD IOSW } 1775febcb4aSScott Carter, SD IOSW 1785febcb4aSScott Carter, SD IOSW if (mdb_pwalk_dcmd("irmreqs", "irmreq", argc, argv, addr) == -1) { 1795febcb4aSScott Carter, SD IOSW mdb_warn("can't walk interrupt requests"); 1805febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 1815febcb4aSScott Carter, SD IOSW } 1825febcb4aSScott Carter, SD IOSW 1835febcb4aSScott Carter, SD IOSW return (DCMD_OK); 1845febcb4aSScott Carter, SD IOSW } 1855febcb4aSScott Carter, SD IOSW 1865febcb4aSScott Carter, SD IOSW /*ARGSUSED*/ 1875febcb4aSScott Carter, SD IOSW int 1885febcb4aSScott Carter, SD IOSW irmreq_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1895febcb4aSScott Carter, SD IOSW { 1905febcb4aSScott Carter, SD IOSW ddi_irm_req_t req; 1915febcb4aSScott Carter, SD IOSW struct dev_info dev; 1925febcb4aSScott Carter, SD IOSW struct devinfo_intr intr; 1935febcb4aSScott Carter, SD IOSW char driver[MODMAXNAMELEN + 1] = ""; 1945febcb4aSScott Carter, SD IOSW char devname[MODMAXNAMELEN + 1] = ""; 1955febcb4aSScott Carter, SD IOSW 1965febcb4aSScott Carter, SD IOSW if (argc != 0) 1975febcb4aSScott Carter, SD IOSW return (DCMD_USAGE); 1985febcb4aSScott Carter, SD IOSW 1995febcb4aSScott Carter, SD IOSW if (!(flags & DCMD_ADDRSPEC)) { 2005febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 2015febcb4aSScott Carter, SD IOSW } 2025febcb4aSScott Carter, SD IOSW 2035febcb4aSScott Carter, SD IOSW if (DCMD_HDRSPEC(flags)) { 2045febcb4aSScott Carter, SD IOSW mdb_printf("%<u>%?s %-18s %-8s %-8s %-6s %-4s " 2055febcb4aSScott Carter, SD IOSW "%-6s%</u>\n", "ADDR", "OWNER", "TYPE", "CALLBACK", 2065febcb4aSScott Carter, SD IOSW "NINTRS", "NREQ", "NAVAIL"); 2075febcb4aSScott Carter, SD IOSW } 2085febcb4aSScott Carter, SD IOSW 2095febcb4aSScott Carter, SD IOSW if (mdb_vread(&req, sizeof (req), addr) != sizeof (req)) { 2105febcb4aSScott Carter, SD IOSW mdb_warn("couldn't read interrupt request at %p", addr); 2115febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 2125febcb4aSScott Carter, SD IOSW } 2135febcb4aSScott Carter, SD IOSW 2145febcb4aSScott Carter, SD IOSW if (mdb_vread(&dev, sizeof (dev), 2155febcb4aSScott Carter, SD IOSW (uintptr_t)req.ireq_dip) != sizeof (dev)) { 2165febcb4aSScott Carter, SD IOSW mdb_warn("couldn't read dev_info at %p", req.ireq_dip); 2175febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 2185febcb4aSScott Carter, SD IOSW } 2195febcb4aSScott Carter, SD IOSW 2205febcb4aSScott Carter, SD IOSW if (mdb_vread(&intr, sizeof (intr), 2215febcb4aSScott Carter, SD IOSW (uintptr_t)dev.devi_intr_p) != sizeof (intr)) { 2225febcb4aSScott Carter, SD IOSW mdb_warn("couldn't read devinfo_intr at %p", dev.devi_intr_p); 2235febcb4aSScott Carter, SD IOSW return (DCMD_ERR); 2245febcb4aSScott Carter, SD IOSW } 2255febcb4aSScott Carter, SD IOSW 2265febcb4aSScott Carter, SD IOSW mdb_devinfo2driver((uintptr_t)req.ireq_dip, driver, sizeof (driver)); 2275febcb4aSScott Carter, SD IOSW mdb_snprintf(devname, sizeof (devname), "%s#%d", driver, 2285febcb4aSScott Carter, SD IOSW dev.devi_instance); 2295febcb4aSScott Carter, SD IOSW 2305febcb4aSScott Carter, SD IOSW mdb_printf("%0?p %-18s %-8s %-8s %-6d %-4d %-6d\n", 2315febcb4aSScott Carter, SD IOSW addr, devname, irm_get_type(req.ireq_type), 2325febcb4aSScott Carter, SD IOSW (req.ireq_flags & DDI_IRM_FLAG_CALLBACK) ? "Yes" : "No", 2335febcb4aSScott Carter, SD IOSW intr.devi_intr_sup_nintrs, req.ireq_nreq, req.ireq_navail); 2345febcb4aSScott Carter, SD IOSW 2355febcb4aSScott Carter, SD IOSW return (DCMD_OK); 2365febcb4aSScott Carter, SD IOSW } 237