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