136fe4a92Segillett /* 236fe4a92Segillett * CDDL HEADER START 336fe4a92Segillett * 436fe4a92Segillett * The contents of this file are subject to the terms of the 520036fe5Segillett * Common Development and Distribution License (the "License"). 620036fe5Segillett * You may not use this file except in compliance with the License. 736fe4a92Segillett * 836fe4a92Segillett * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 936fe4a92Segillett * or http://www.opensolaris.org/os/licensing. 1036fe4a92Segillett * See the License for the specific language governing permissions 1136fe4a92Segillett * and limitations under the License. 1236fe4a92Segillett * 1336fe4a92Segillett * When distributing Covered Code, include this CDDL HEADER in each 1436fe4a92Segillett * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1536fe4a92Segillett * If applicable, add the following below this CDDL HEADER, with the 1636fe4a92Segillett * fields enclosed by brackets "[]" replaced with your own identifying 1736fe4a92Segillett * information: Portions Copyright [yyyy] [name of copyright owner] 1836fe4a92Segillett * 1936fe4a92Segillett * CDDL HEADER END 2036fe4a92Segillett */ 2136fe4a92Segillett /* 22*500b1e78SAlan Adamson, SD OSSD * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 2336fe4a92Segillett * Use is subject to license terms. 2436fe4a92Segillett */ 2536fe4a92Segillett 2636fe4a92Segillett #include <sys/mdb_modapi.h> 2736fe4a92Segillett #include <mdb/mdb_ks.h> 2836fe4a92Segillett #include <sys/async.h> /* ecc_flt for pci_ecc.h */ 2936fe4a92Segillett #include <sys/ddi_subrdefs.h> 3036fe4a92Segillett #include <sys/pci/pci_obj.h> 31*500b1e78SAlan Adamson, SD OSSD #include "niumx_var.h" 3236fe4a92Segillett #include "px_obj.h" 3336fe4a92Segillett 3436fe4a92Segillett static int intr_pci_walk_step(mdb_walk_state_t *); 3536fe4a92Segillett static int intr_px_walk_step(mdb_walk_state_t *); 36*500b1e78SAlan Adamson, SD OSSD static int intr_niumx_walk_step(mdb_walk_state_t *); 3736fe4a92Segillett static void intr_pci_print_items(mdb_walk_state_t *); 3836fe4a92Segillett static void intr_px_print_items(mdb_walk_state_t *); 3920036fe5Segillett static char *intr_get_intr_type(uint16_t type); 4036fe4a92Segillett static void intr_print_banner(void); 4136fe4a92Segillett 4236fe4a92Segillett typedef struct intr_info { 4336fe4a92Segillett uint32_t cpuid; 4436fe4a92Segillett uint32_t inum; 4536fe4a92Segillett uint32_t num; 4636fe4a92Segillett uint32_t pil; 4720036fe5Segillett uint16_t intr_type; 4836fe4a92Segillett uint16_t mondo; 4936fe4a92Segillett uint8_t ino_ino; 5036fe4a92Segillett uint_t intr_state; 5136fe4a92Segillett int instance; 5236fe4a92Segillett int shared; 5336fe4a92Segillett char driver_name[12]; 5436fe4a92Segillett char pathname[MAXNAMELEN]; 5536fe4a92Segillett } 5636fe4a92Segillett intr_info_t; 5736fe4a92Segillett 582419d3ccSegillett #define PX_MAX_ENTRIES 32 592419d3ccSegillett 6036fe4a92Segillett static void intr_print_elements(intr_info_t); 6136fe4a92Segillett static int detailed = 0; /* Print detailed view */ 6236fe4a92Segillett 6336fe4a92Segillett 6436fe4a92Segillett static int 6536fe4a92Segillett intr_walk_init(mdb_walk_state_t *wsp) 6636fe4a92Segillett { 6736fe4a92Segillett wsp->walk_addr = NULL; 6836fe4a92Segillett 6936fe4a92Segillett return (WALK_NEXT); 7036fe4a92Segillett } 7136fe4a92Segillett 7236fe4a92Segillett static int 7336fe4a92Segillett intr_walk_step(mdb_walk_state_t *wsp) 7436fe4a92Segillett { 7536fe4a92Segillett pci_t *pci_per_p; 7636fe4a92Segillett px_t *px_state_p; 77*500b1e78SAlan Adamson, SD OSSD niumx_devstate_t *niumx_state_p; 7836fe4a92Segillett 7936fe4a92Segillett /* read globally declared structures in the pci driver */ 8036fe4a92Segillett if (mdb_readvar(&pci_per_p, "per_pci_state") != -1) { 8136fe4a92Segillett wsp->walk_addr = (uintptr_t)pci_per_p; 8236fe4a92Segillett intr_pci_walk_step(wsp); 8336fe4a92Segillett } 8436fe4a92Segillett 8536fe4a92Segillett /* read globally declared structures in the px driver */ 8636fe4a92Segillett if (mdb_readvar(&px_state_p, "px_state_p") != -1) { 8736fe4a92Segillett wsp->walk_addr = (uintptr_t)px_state_p; 8836fe4a92Segillett intr_px_walk_step(wsp); 8936fe4a92Segillett } 9036fe4a92Segillett 91*500b1e78SAlan Adamson, SD OSSD /* read globally declared structures in the niumx driver */ 92*500b1e78SAlan Adamson, SD OSSD if (mdb_readvar(&niumx_state_p, "niumx_state") != -1) { 93*500b1e78SAlan Adamson, SD OSSD wsp->walk_addr = (uintptr_t)niumx_state_p; 94*500b1e78SAlan Adamson, SD OSSD intr_niumx_walk_step(wsp); 95*500b1e78SAlan Adamson, SD OSSD } 96*500b1e78SAlan Adamson, SD OSSD 9736fe4a92Segillett return (WALK_DONE); 9836fe4a92Segillett } 9936fe4a92Segillett 10036fe4a92Segillett static int 10136fe4a92Segillett intr_pci_walk_step(mdb_walk_state_t *wsp) 10236fe4a92Segillett { 10336fe4a92Segillett pci_t *pci_per_p; 10436fe4a92Segillett pci_t pci_per; 10536fe4a92Segillett uintptr_t start_addr; 10636fe4a92Segillett 10736fe4a92Segillett /* Read start of state structure array */ 10836fe4a92Segillett if (mdb_vread(&pci_per_p, sizeof (uintptr_t), 10936fe4a92Segillett (uintptr_t)wsp->walk_addr) == -1) { 11036fe4a92Segillett mdb_warn("intr: failed to read the initial pci_per_p " 11136fe4a92Segillett "structure\n"); 11236fe4a92Segillett return (WALK_ERR); 11336fe4a92Segillett } 11436fe4a92Segillett 11536fe4a92Segillett /* Figure out how many items are here */ 11636fe4a92Segillett start_addr = (uintptr_t)pci_per_p; 11736fe4a92Segillett 1189c75c6bfSgovinda intr_print_banner(); 1199c75c6bfSgovinda 12036fe4a92Segillett while (mdb_vread(&pci_per_p, sizeof (uintptr_t), 12136fe4a92Segillett (uintptr_t)start_addr) != -1) { 12236fe4a92Segillett /* Read until nothing is left */ 12336fe4a92Segillett if (mdb_vread(&pci_per, sizeof (pci_t), 12436fe4a92Segillett (uintptr_t)pci_per_p) == -1) { 12536fe4a92Segillett return (WALK_DONE); 12636fe4a92Segillett } 12736fe4a92Segillett 12836fe4a92Segillett wsp->walk_addr = (uintptr_t)pci_per.pci_ib_p; 12936fe4a92Segillett intr_pci_print_items(wsp); 13036fe4a92Segillett 13136fe4a92Segillett start_addr += sizeof (uintptr_t); 13236fe4a92Segillett } 13336fe4a92Segillett 13436fe4a92Segillett return (WALK_DONE); 13536fe4a92Segillett } 13636fe4a92Segillett 13736fe4a92Segillett static int 13836fe4a92Segillett intr_px_walk_step(mdb_walk_state_t *wsp) 13936fe4a92Segillett { 14036fe4a92Segillett px_t *px_state_p; 14136fe4a92Segillett px_t px_state; 14236fe4a92Segillett uintptr_t start_addr; 1432419d3ccSegillett int x; 14436fe4a92Segillett 14536fe4a92Segillett /* Read start of state structure array */ 14636fe4a92Segillett if (mdb_vread(&px_state_p, sizeof (uintptr_t), 14736fe4a92Segillett (uintptr_t)wsp->walk_addr) == -1) { 14836fe4a92Segillett mdb_warn("intr: failed to read the initial px_per_p " 14936fe4a92Segillett "structure\n"); 15036fe4a92Segillett return (WALK_ERR); 15136fe4a92Segillett } 15236fe4a92Segillett 15336fe4a92Segillett /* Figure out how many items are here */ 15436fe4a92Segillett start_addr = (uintptr_t)px_state_p; 15536fe4a92Segillett 1569c75c6bfSgovinda intr_print_banner(); 1579c75c6bfSgovinda 1582419d3ccSegillett for (x = 0; x < PX_MAX_ENTRIES; x++) { 1592419d3ccSegillett (void) mdb_vread(&px_state_p, sizeof (uintptr_t), 1602419d3ccSegillett (uintptr_t)start_addr); 1612419d3ccSegillett 1622419d3ccSegillett start_addr += sizeof (uintptr_t); 1632419d3ccSegillett 1642419d3ccSegillett /* Read if anything is there */ 16536fe4a92Segillett if (mdb_vread(&px_state, sizeof (px_t), 16636fe4a92Segillett (uintptr_t)px_state_p) == -1) { 1672419d3ccSegillett continue; 16836fe4a92Segillett } 16936fe4a92Segillett 17036fe4a92Segillett wsp->walk_addr = (uintptr_t)px_state.px_ib_p; 17136fe4a92Segillett intr_px_print_items(wsp); 17236fe4a92Segillett } 17336fe4a92Segillett 17436fe4a92Segillett return (WALK_DONE); 17536fe4a92Segillett } 17636fe4a92Segillett 177*500b1e78SAlan Adamson, SD OSSD static int 178*500b1e78SAlan Adamson, SD OSSD intr_niumx_walk_step(mdb_walk_state_t *wsp) 179*500b1e78SAlan Adamson, SD OSSD { 180*500b1e78SAlan Adamson, SD OSSD niumx_devstate_t *niumx_state_p; 181*500b1e78SAlan Adamson, SD OSSD niumx_devstate_t niumx_state; 182*500b1e78SAlan Adamson, SD OSSD uintptr_t start_addr; 183*500b1e78SAlan Adamson, SD OSSD char name[MODMAXNAMELEN + 1]; 184*500b1e78SAlan Adamson, SD OSSD struct dev_info dev; 185*500b1e78SAlan Adamson, SD OSSD intr_info_t info; 186*500b1e78SAlan Adamson, SD OSSD int i; 187*500b1e78SAlan Adamson, SD OSSD 188*500b1e78SAlan Adamson, SD OSSD /* Read start of state structure array */ 189*500b1e78SAlan Adamson, SD OSSD if (mdb_vread(&niumx_state_p, sizeof (uintptr_t), 190*500b1e78SAlan Adamson, SD OSSD (uintptr_t)wsp->walk_addr) == -1) { 191*500b1e78SAlan Adamson, SD OSSD mdb_warn("intr: failed to read the initial niumx_state_p " 192*500b1e78SAlan Adamson, SD OSSD "structure\n"); 193*500b1e78SAlan Adamson, SD OSSD return (WALK_ERR); 194*500b1e78SAlan Adamson, SD OSSD } 195*500b1e78SAlan Adamson, SD OSSD 196*500b1e78SAlan Adamson, SD OSSD /* Figure out how many items are here */ 197*500b1e78SAlan Adamson, SD OSSD start_addr = (uintptr_t)niumx_state_p; 198*500b1e78SAlan Adamson, SD OSSD 199*500b1e78SAlan Adamson, SD OSSD while (mdb_vread(&niumx_state_p, sizeof (uintptr_t), 200*500b1e78SAlan Adamson, SD OSSD (uintptr_t)start_addr) >= 0) { 201*500b1e78SAlan Adamson, SD OSSD 202*500b1e78SAlan Adamson, SD OSSD start_addr += sizeof (uintptr_t); 203*500b1e78SAlan Adamson, SD OSSD 204*500b1e78SAlan Adamson, SD OSSD /* Read if anything is there */ 205*500b1e78SAlan Adamson, SD OSSD if (mdb_vread(&niumx_state, sizeof (niumx_devstate_t), 206*500b1e78SAlan Adamson, SD OSSD (uintptr_t)niumx_state_p) == -1) { 207*500b1e78SAlan Adamson, SD OSSD return (WALK_DONE); 208*500b1e78SAlan Adamson, SD OSSD } 209*500b1e78SAlan Adamson, SD OSSD 210*500b1e78SAlan Adamson, SD OSSD for (i = 0; i < NIUMX_MAX_INTRS; i++) { 211*500b1e78SAlan Adamson, SD OSSD if (niumx_state.niumx_ihtable[i].ih_sysino == 0) 212*500b1e78SAlan Adamson, SD OSSD continue; 213*500b1e78SAlan Adamson, SD OSSD 214*500b1e78SAlan Adamson, SD OSSD if (niumx_state.niumx_ihtable[i].ih_dip == 0) 215*500b1e78SAlan Adamson, SD OSSD continue; 216*500b1e78SAlan Adamson, SD OSSD 217*500b1e78SAlan Adamson, SD OSSD bzero((void *)&info, sizeof (intr_info_t)); 218*500b1e78SAlan Adamson, SD OSSD 219*500b1e78SAlan Adamson, SD OSSD info.shared = 0; 220*500b1e78SAlan Adamson, SD OSSD 221*500b1e78SAlan Adamson, SD OSSD (void) mdb_devinfo2driver( 222*500b1e78SAlan Adamson, SD OSSD (uintptr_t)niumx_state.niumx_ihtable[i].ih_dip, 223*500b1e78SAlan Adamson, SD OSSD name, sizeof (name)); 224*500b1e78SAlan Adamson, SD OSSD 225*500b1e78SAlan Adamson, SD OSSD (void) mdb_ddi_pathname( 226*500b1e78SAlan Adamson, SD OSSD (uintptr_t)niumx_state.niumx_ihtable[i].ih_dip, 227*500b1e78SAlan Adamson, SD OSSD info.pathname, sizeof (info.pathname)); 228*500b1e78SAlan Adamson, SD OSSD 229*500b1e78SAlan Adamson, SD OSSD /* Get instance */ 230*500b1e78SAlan Adamson, SD OSSD if (mdb_vread(&dev, sizeof (struct dev_info), 231*500b1e78SAlan Adamson, SD OSSD (uintptr_t)niumx_state.niumx_ihtable[i].ih_dip) == 232*500b1e78SAlan Adamson, SD OSSD -1) { 233*500b1e78SAlan Adamson, SD OSSD mdb_warn("intr: failed to read DIP " 234*500b1e78SAlan Adamson, SD OSSD "structure\n"); 235*500b1e78SAlan Adamson, SD OSSD 236*500b1e78SAlan Adamson, SD OSSD return (WALK_DONE); 237*500b1e78SAlan Adamson, SD OSSD } 238*500b1e78SAlan Adamson, SD OSSD 239*500b1e78SAlan Adamson, SD OSSD /* Make sure the name doesn't over run */ 240*500b1e78SAlan Adamson, SD OSSD (void) mdb_snprintf(info.driver_name, 241*500b1e78SAlan Adamson, SD OSSD sizeof (info.driver_name), "%s", name); 242*500b1e78SAlan Adamson, SD OSSD 243*500b1e78SAlan Adamson, SD OSSD info.instance = dev.devi_instance; 244*500b1e78SAlan Adamson, SD OSSD info.inum = niumx_state.niumx_ihtable[i].ih_inum; 245*500b1e78SAlan Adamson, SD OSSD info.intr_type = DDI_INTR_TYPE_FIXED; 246*500b1e78SAlan Adamson, SD OSSD info.num = 0; 247*500b1e78SAlan Adamson, SD OSSD info.intr_state = niumx_state.niumx_ihtable[i].ih_state; 248*500b1e78SAlan Adamson, SD OSSD info.ino_ino = i; 249*500b1e78SAlan Adamson, SD OSSD info.mondo = niumx_state.niumx_ihtable[i].ih_sysino; 250*500b1e78SAlan Adamson, SD OSSD info.pil = niumx_state.niumx_ihtable[i].ih_pri; 251*500b1e78SAlan Adamson, SD OSSD info.cpuid = niumx_state.niumx_ihtable[i].ih_cpuid; 252*500b1e78SAlan Adamson, SD OSSD 253*500b1e78SAlan Adamson, SD OSSD intr_print_elements(info); 254*500b1e78SAlan Adamson, SD OSSD } 255*500b1e78SAlan Adamson, SD OSSD } 256*500b1e78SAlan Adamson, SD OSSD 257*500b1e78SAlan Adamson, SD OSSD return (WALK_DONE); 258*500b1e78SAlan Adamson, SD OSSD } 259*500b1e78SAlan Adamson, SD OSSD 26036fe4a92Segillett static void 26136fe4a92Segillett intr_pci_print_items(mdb_walk_state_t *wsp) 26236fe4a92Segillett { 263b0fc0e77Sgovinda ib_t ib; 264b0fc0e77Sgovinda ib_ino_info_t ino; 265b0fc0e77Sgovinda ib_ino_pil_t ipil; 26636fe4a92Segillett ih_t ih; 26736fe4a92Segillett int count; 26836fe4a92Segillett char name[MODMAXNAMELEN + 1]; 269b0fc0e77Sgovinda struct dev_info dev; 27036fe4a92Segillett intr_info_t info; 27136fe4a92Segillett 272b0fc0e77Sgovinda if (mdb_vread(&ib, sizeof (ib_t), 27336fe4a92Segillett (uintptr_t)wsp->walk_addr) == -1) { 27436fe4a92Segillett mdb_warn("intr: failed to read pci interrupt block " 27536fe4a92Segillett "structure\n"); 27636fe4a92Segillett return; 27736fe4a92Segillett } 27836fe4a92Segillett 27936fe4a92Segillett /* Read in ib_ino_info_t structure at address */ 280b0fc0e77Sgovinda if (mdb_vread(&ino, sizeof (ib_ino_info_t), 281b0fc0e77Sgovinda (uintptr_t)ib.ib_ino_lst) == -1) { 28236fe4a92Segillett /* Nothing here to read from */ 28336fe4a92Segillett return; 28436fe4a92Segillett } 28536fe4a92Segillett 28636fe4a92Segillett do { 287b0fc0e77Sgovinda if (mdb_vread(&ipil, sizeof (ib_ino_pil_t), 288b0fc0e77Sgovinda (uintptr_t)ino.ino_ipil_p) == -1) { 289b0fc0e77Sgovinda mdb_warn("intr: failed to read pci interrupt " 290b0fc0e77Sgovinda "ib_ino_pil_t structure\n"); 291b0fc0e77Sgovinda return; 292b0fc0e77Sgovinda } 293b0fc0e77Sgovinda 294b0fc0e77Sgovinda do { 29536fe4a92Segillett if (mdb_vread(&ih, sizeof (ih_t), 296b0fc0e77Sgovinda (uintptr_t)ipil.ipil_ih_start) == -1) { 297b0fc0e77Sgovinda mdb_warn("intr: failed to read pci interrupt " 298b0fc0e77Sgovinda "ih_t structure\n"); 29936fe4a92Segillett return; 30036fe4a92Segillett } 30136fe4a92Segillett 30236fe4a92Segillett count = 0; 30336fe4a92Segillett 30436fe4a92Segillett do { 30536fe4a92Segillett bzero((void *)&info, sizeof (intr_info_t)); 30636fe4a92Segillett 307b0fc0e77Sgovinda if ((ino.ino_ipil_size > 1) || 308b0fc0e77Sgovinda (ipil.ipil_ih_size > 1)) { 30936fe4a92Segillett info.shared = 1; 31036fe4a92Segillett } 31136fe4a92Segillett 31236fe4a92Segillett (void) mdb_devinfo2driver((uintptr_t)ih.ih_dip, 31336fe4a92Segillett name, sizeof (name)); 31436fe4a92Segillett 31536fe4a92Segillett (void) mdb_ddi_pathname((uintptr_t)ih.ih_dip, 31636fe4a92Segillett info.pathname, sizeof (info.pathname)); 31736fe4a92Segillett 31836fe4a92Segillett /* Get instance */ 319b0fc0e77Sgovinda if (mdb_vread(&dev, sizeof (struct dev_info), 32036fe4a92Segillett (uintptr_t)ih.ih_dip) == -1) { 32136fe4a92Segillett mdb_warn("intr: failed to read DIP " 32236fe4a92Segillett "structure\n"); 32336fe4a92Segillett return; 32436fe4a92Segillett } 32536fe4a92Segillett 32636fe4a92Segillett /* Make sure the name doesn't over run */ 32736fe4a92Segillett (void) mdb_snprintf(info.driver_name, 32836fe4a92Segillett sizeof (info.driver_name), "%s", name); 32936fe4a92Segillett 330b0fc0e77Sgovinda info.instance = dev.devi_instance; 33136fe4a92Segillett info.inum = ih.ih_inum; 33220036fe5Segillett info.intr_type = DDI_INTR_TYPE_FIXED; 33336fe4a92Segillett info.num = 0; 33436fe4a92Segillett info.intr_state = ih.ih_intr_state; 335b0fc0e77Sgovinda info.ino_ino = ino.ino_ino; 336b0fc0e77Sgovinda info.mondo = ino.ino_mondo; 337b0fc0e77Sgovinda info.pil = ipil.ipil_pil; 338b0fc0e77Sgovinda info.cpuid = ino.ino_cpuid; 33936fe4a92Segillett 34036fe4a92Segillett intr_print_elements(info); 34136fe4a92Segillett count++; 34236fe4a92Segillett 34336fe4a92Segillett (void) mdb_vread(&ih, sizeof (ih_t), 34436fe4a92Segillett (uintptr_t)ih.ih_next); 34536fe4a92Segillett 346b0fc0e77Sgovinda } while (count < ipil.ipil_ih_size); 34736fe4a92Segillett 348b0fc0e77Sgovinda } while (mdb_vread(&ipil, sizeof (ib_ino_pil_t), 349b0fc0e77Sgovinda (uintptr_t)ipil.ipil_next_p) != -1); 350b0fc0e77Sgovinda 351b0fc0e77Sgovinda } while (mdb_vread(&ino, sizeof (ib_ino_info_t), 352b0fc0e77Sgovinda (uintptr_t)ino.ino_next_p) != -1); 35336fe4a92Segillett } 35436fe4a92Segillett 35536fe4a92Segillett static void 35636fe4a92Segillett intr_px_print_items(mdb_walk_state_t *wsp) 35736fe4a92Segillett { 358b0fc0e77Sgovinda px_ib_t ib; 359b0fc0e77Sgovinda px_ino_t ino; 360b0fc0e77Sgovinda px_ino_pil_t ipil; 361b0fc0e77Sgovinda px_ih_t ih; 36236fe4a92Segillett int count; 36336fe4a92Segillett char name[MODMAXNAMELEN + 1]; 364b0fc0e77Sgovinda struct dev_info dev; 36536fe4a92Segillett intr_info_t info; 36620036fe5Segillett devinfo_intr_t intr_p; 36736fe4a92Segillett 368b0fc0e77Sgovinda if (mdb_vread(&ib, sizeof (px_ib_t), wsp->walk_addr) == -1) { 36936fe4a92Segillett return; 37036fe4a92Segillett } 37136fe4a92Segillett 372b0fc0e77Sgovinda /* Read in px_ino_t structure at address */ 373b0fc0e77Sgovinda if (mdb_vread(&ino, sizeof (px_ino_t), 374b0fc0e77Sgovinda (uintptr_t)ib.ib_ino_lst) == -1) { 37536fe4a92Segillett /* Nothing here to read from */ 37636fe4a92Segillett return; 37736fe4a92Segillett } 37836fe4a92Segillett 3792419d3ccSegillett do { /* ino_next_p loop */ 380b0fc0e77Sgovinda if (mdb_vread(&ipil, sizeof (px_ino_pil_t), 381b0fc0e77Sgovinda (uintptr_t)ino.ino_ipil_p) == -1) { 38209b1eac2SEvan Yan continue; 383b0fc0e77Sgovinda } 384b0fc0e77Sgovinda 3852419d3ccSegillett do { /* ipil_next_p loop */ 386b0fc0e77Sgovinda if (mdb_vread(&ih, sizeof (px_ih_t), 387b0fc0e77Sgovinda (uintptr_t)ipil.ipil_ih_start) == -1) { 38809b1eac2SEvan Yan continue; 38936fe4a92Segillett } 39036fe4a92Segillett 39136fe4a92Segillett count = 0; 39236fe4a92Segillett 3932419d3ccSegillett do { /* ipil_ih_size loop */ 39436fe4a92Segillett bzero((void *)&info, sizeof (intr_info_t)); 39536fe4a92Segillett 396b0fc0e77Sgovinda (void) mdb_devinfo2driver((uintptr_t)ih.ih_dip, 39736fe4a92Segillett name, sizeof (name)); 39836fe4a92Segillett 399b0fc0e77Sgovinda (void) mdb_ddi_pathname((uintptr_t)ih.ih_dip, 40036fe4a92Segillett info.pathname, sizeof (info.pathname)); 40136fe4a92Segillett 40236fe4a92Segillett /* Get instance */ 403b0fc0e77Sgovinda if (mdb_vread(&dev, sizeof (struct dev_info), 404b0fc0e77Sgovinda (uintptr_t)ih.ih_dip) == -1) { 40536fe4a92Segillett mdb_warn("intr: failed to read DIP " 40636fe4a92Segillett "structure\n"); 40736fe4a92Segillett return; 40836fe4a92Segillett } 40936fe4a92Segillett 41036fe4a92Segillett /* Make sure the name doesn't over run */ 41136fe4a92Segillett (void) mdb_snprintf(info.driver_name, 41236fe4a92Segillett sizeof (info.driver_name), "%s", name); 41336fe4a92Segillett 414b0fc0e77Sgovinda info.instance = dev.devi_instance; 415b0fc0e77Sgovinda info.inum = ih.ih_inum; 41620036fe5Segillett 417b0fc0e77Sgovinda /* 418b0fc0e77Sgovinda * Read the type used, keep PCIe messages 419b0fc0e77Sgovinda * separate. 420b0fc0e77Sgovinda */ 421b0fc0e77Sgovinda (void) mdb_vread(&intr_p, 422b0fc0e77Sgovinda sizeof (devinfo_intr_t), 423b0fc0e77Sgovinda (uintptr_t)dev.devi_intr_p); 424b0fc0e77Sgovinda 425b0fc0e77Sgovinda if (ih.ih_rec_type != MSG_REC) { 426b0fc0e77Sgovinda info.intr_type = 427b0fc0e77Sgovinda intr_p.devi_intr_curr_type; 42820036fe5Segillett } 42920036fe5Segillett 43022edf370SDaniel Ice if ((ino.ino_ipil_size > 1) || 43122edf370SDaniel Ice (ipil.ipil_ih_size > 1)) { 432b0fc0e77Sgovinda info.shared = 1; 433b0fc0e77Sgovinda } 434b0fc0e77Sgovinda 435b0fc0e77Sgovinda info.num = ih.ih_msg_code; 436b0fc0e77Sgovinda info.intr_state = ih.ih_intr_state; 437b0fc0e77Sgovinda info.ino_ino = ino.ino_ino; 438b0fc0e77Sgovinda info.mondo = ino.ino_sysino; 439b0fc0e77Sgovinda info.pil = ipil.ipil_pil; 440b0fc0e77Sgovinda info.cpuid = ino.ino_cpuid; 44136fe4a92Segillett 44236fe4a92Segillett intr_print_elements(info); 44336fe4a92Segillett count++; 44436fe4a92Segillett 445b0fc0e77Sgovinda (void) mdb_vread(&ih, sizeof (px_ih_t), 446b0fc0e77Sgovinda (uintptr_t)ih.ih_next); 44736fe4a92Segillett 448b0fc0e77Sgovinda } while (count < ipil.ipil_ih_size); 44936fe4a92Segillett 45009b1eac2SEvan Yan } while ((ipil.ipil_next_p != NULL) && 45109b1eac2SEvan Yan (mdb_vread(&ipil, sizeof (px_ino_pil_t), 45209b1eac2SEvan Yan (uintptr_t)ipil.ipil_next_p) != -1)); 453b0fc0e77Sgovinda 45409b1eac2SEvan Yan } while ((ino.ino_next_p != NULL) && (mdb_vread(&ino, sizeof (px_ino_t), 45509b1eac2SEvan Yan (uintptr_t)ino.ino_next_p) != -1)); 45636fe4a92Segillett } 45736fe4a92Segillett 45836fe4a92Segillett static char * 45920036fe5Segillett intr_get_intr_type(uint16_t type) 46036fe4a92Segillett { 46120036fe5Segillett switch (type) { 46220036fe5Segillett case DDI_INTR_TYPE_FIXED: 46336fe4a92Segillett return ("Fixed"); 46420036fe5Segillett case DDI_INTR_TYPE_MSI: 46520036fe5Segillett return ("MSI"); 46620036fe5Segillett case DDI_INTR_TYPE_MSIX: 46720036fe5Segillett return ("MSI-X"); 46820036fe5Segillett default: 46920036fe5Segillett return ("PCIe"); 47036fe4a92Segillett } 47136fe4a92Segillett } 47236fe4a92Segillett 47336fe4a92Segillett static void 47436fe4a92Segillett intr_print_banner(void) 47536fe4a92Segillett { 47636fe4a92Segillett if (!detailed) { 4779c75c6bfSgovinda mdb_printf("\n%<u>\tDevice\t" 4789c75c6bfSgovinda " Type\t" 4799c75c6bfSgovinda " MSG #\t" 4809c75c6bfSgovinda " State\t" 4819c75c6bfSgovinda " INO\t" 4829c75c6bfSgovinda " Mondo\t" 48322edf370SDaniel Ice " Shared\t" 4849c75c6bfSgovinda " Pil\t" 4859c75c6bfSgovinda " CPU %</u>" 4869c75c6bfSgovinda "\n"); 48736fe4a92Segillett } 48836fe4a92Segillett } 48936fe4a92Segillett 49036fe4a92Segillett static void 49136fe4a92Segillett intr_print_elements(intr_info_t info) 49236fe4a92Segillett { 49336fe4a92Segillett if (!detailed) { 4949c75c6bfSgovinda mdb_printf(" %11s#%d\t", info.driver_name, info.instance); 4959c75c6bfSgovinda mdb_printf(" %s\t", intr_get_intr_type(info.intr_type)); 49620036fe5Segillett if (info.intr_type == DDI_INTR_TYPE_FIXED) { 4979c75c6bfSgovinda mdb_printf(" --- \t"); 49836fe4a92Segillett } else { 4999c75c6bfSgovinda mdb_printf(" %4d\t", info.num); 50036fe4a92Segillett } 5019c75c6bfSgovinda mdb_printf(" %2s\t", 50236fe4a92Segillett info.intr_state ? "enbl" : "disbl"); 5039c75c6bfSgovinda mdb_printf(" 0x%x\t", info.ino_ino); 5049c75c6bfSgovinda mdb_printf(" 0x%x\t", info.mondo); 50522edf370SDaniel Ice mdb_printf(" %5s\t", 50622edf370SDaniel Ice info.shared ? "yes" : "no"); 5079c75c6bfSgovinda mdb_printf(" %4d\t", info.pil); 5089c75c6bfSgovinda mdb_printf(" %3d \n", info.cpuid); 50936fe4a92Segillett } else { 51036fe4a92Segillett mdb_printf("\n-------------------------------------------\n"); 51136fe4a92Segillett mdb_printf("Device:\t\t%s\n", info.driver_name); 51236fe4a92Segillett mdb_printf("Instance:\t%d\n", info.instance); 51336fe4a92Segillett mdb_printf("Path:\t\t%s\n", info.pathname); 51436fe4a92Segillett mdb_printf("Inum:\t\t%d\n", info.inum); 51536fe4a92Segillett mdb_printf("Interrupt Type:\t%s\n", 51636fe4a92Segillett intr_get_intr_type(info.intr_type)); 51720036fe5Segillett if (info.intr_type == DDI_INTR_TYPE_MSI) { 51820036fe5Segillett mdb_printf("MSI Number:\t%d\n", info.num); 51920036fe5Segillett } else if (info.intr_type == DDI_INTR_TYPE_MSIX) { 52020036fe5Segillett mdb_printf("MSI-X Number:\t%d\n", info.num); 52120036fe5Segillett } else if (!info.intr_type) { 52220036fe5Segillett mdb_printf("PCIe Message #:\t%d\n", info.num); 52320036fe5Segillett } 52436fe4a92Segillett 52536fe4a92Segillett mdb_printf("Shared Intr:\t%s\n", 52636fe4a92Segillett info.shared ? "yes" : "no"); 52736fe4a92Segillett mdb_printf("State:\t\t%d (%s)\n", info.intr_state, 52836fe4a92Segillett info.intr_state ? "Enabled" : "Disabled"); 52936fe4a92Segillett mdb_printf("INO:\t\t0x%x\n", info.ino_ino); 53036fe4a92Segillett mdb_printf("Mondo:\t\t0x%x\n", info.mondo); 53136fe4a92Segillett mdb_printf("Pil:\t\t%d\n", info.pil); 53236fe4a92Segillett mdb_printf("CPU:\t\t%d\n", info.cpuid); 53336fe4a92Segillett } 53436fe4a92Segillett } 53536fe4a92Segillett 53636fe4a92Segillett /*ARGSUSED*/ 53736fe4a92Segillett static void 53836fe4a92Segillett intr_walk_fini(mdb_walk_state_t *wsp) 53936fe4a92Segillett { 54036fe4a92Segillett /* Nothing to do here */ 54136fe4a92Segillett } 54236fe4a92Segillett 54336fe4a92Segillett /*ARGSUSED*/ 54436fe4a92Segillett static int 54536fe4a92Segillett intr_intr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 54636fe4a92Segillett { 54736fe4a92Segillett detailed = 0; 54836fe4a92Segillett 54936fe4a92Segillett if (mdb_getopts(argc, argv, 'd', MDB_OPT_SETBITS, TRUE, &detailed, 55036fe4a92Segillett NULL) != argc) 55136fe4a92Segillett return (DCMD_USAGE); 55236fe4a92Segillett 55336fe4a92Segillett if (!(flags & DCMD_ADDRSPEC)) { 55436fe4a92Segillett if (mdb_walk_dcmd("interrupts", "interrupts", argc, argv) 55536fe4a92Segillett == -1) { 55636fe4a92Segillett mdb_warn("can't walk pci/px buffer entries\n"); 55736fe4a92Segillett return (DCMD_ERR); 55836fe4a92Segillett } 55936fe4a92Segillett return (DCMD_OK); 56036fe4a92Segillett } 56136fe4a92Segillett 56236fe4a92Segillett return (DCMD_OK); 56336fe4a92Segillett } 56436fe4a92Segillett 56536fe4a92Segillett /* 56636fe4a92Segillett * MDB module linkage information: 56736fe4a92Segillett */ 56836fe4a92Segillett 56936fe4a92Segillett static const mdb_dcmd_t dcmds[] = { 57036fe4a92Segillett { "interrupts", "[-d]", "display the interrupt info registered with " 57136fe4a92Segillett "the PCI/PX nexus drivers", intr_intr }, 57236fe4a92Segillett { NULL } 57336fe4a92Segillett }; 57436fe4a92Segillett 57536fe4a92Segillett static const mdb_walker_t walkers[] = { 57636fe4a92Segillett { "interrupts", "walk PCI/PX interrupt structures", 57736fe4a92Segillett intr_walk_init, intr_walk_step, intr_walk_fini }, 57836fe4a92Segillett { NULL } 57936fe4a92Segillett }; 58036fe4a92Segillett 58136fe4a92Segillett static const mdb_modinfo_t modinfo = { 58236fe4a92Segillett MDB_API_VERSION, dcmds, walkers 58336fe4a92Segillett }; 58436fe4a92Segillett 58536fe4a92Segillett const mdb_modinfo_t * 58636fe4a92Segillett _mdb_init(void) 58736fe4a92Segillett { 58836fe4a92Segillett return (&modinfo); 58936fe4a92Segillett } 590