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
intr_walk_init(mdb_walk_state_t * wsp)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
intr_walk_step(mdb_walk_state_t * wsp)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
intr_pci_walk_step(mdb_walk_state_t * wsp)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
intr_px_walk_step(mdb_walk_state_t * wsp)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
intr_niumx_walk_step(mdb_walk_state_t * wsp)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
intr_pci_print_items(mdb_walk_state_t * wsp)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
intr_px_print_items(mdb_walk_state_t * wsp)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 *
intr_get_intr_type(uint16_t type)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
intr_print_banner(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
intr_print_elements(intr_info_t info)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
intr_walk_fini(mdb_walk_state_t * wsp)53836fe4a92Segillett intr_walk_fini(mdb_walk_state_t *wsp)
53936fe4a92Segillett {
54036fe4a92Segillett /* Nothing to do here */
54136fe4a92Segillett }
54236fe4a92Segillett
54336fe4a92Segillett /*ARGSUSED*/
54436fe4a92Segillett static int
intr_intr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)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 *
_mdb_init(void)58636fe4a92Segillett _mdb_init(void)
58736fe4a92Segillett {
58836fe4a92Segillett return (&modinfo);
58936fe4a92Segillett }
590