1909Segillett /*
2909Segillett * CDDL HEADER START
3909Segillett *
4909Segillett * The contents of this file are subject to the terms of the
51725Segillett * Common Development and Distribution License (the "License").
61725Segillett * You may not use this file except in compliance with the License.
7909Segillett *
8909Segillett * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9909Segillett * or http://www.opensolaris.org/os/licensing.
10909Segillett * See the License for the specific language governing permissions
11909Segillett * and limitations under the License.
12909Segillett *
13909Segillett * When distributing Covered Code, include this CDDL HEADER in each
14909Segillett * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15909Segillett * If applicable, add the following below this CDDL HEADER, with the
16909Segillett * fields enclosed by brackets "[]" replaced with your own identifying
17909Segillett * information: Portions Copyright [yyyy] [name of copyright owner]
18909Segillett *
19909Segillett * CDDL HEADER END
20909Segillett */
21909Segillett /*
22*11513SAlan.Adamson@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23909Segillett * Use is subject to license terms.
24909Segillett */
25909Segillett
26909Segillett #include <sys/mdb_modapi.h>
27909Segillett #include <mdb/mdb_ks.h>
28909Segillett #include <sys/async.h> /* ecc_flt for pci_ecc.h */
29909Segillett #include <sys/ddi_subrdefs.h>
30909Segillett #include <sys/pci/pci_obj.h>
31*11513SAlan.Adamson@Sun.COM #include "niumx_var.h"
32909Segillett #include "px_obj.h"
33909Segillett
34909Segillett static int intr_pci_walk_step(mdb_walk_state_t *);
35909Segillett static int intr_px_walk_step(mdb_walk_state_t *);
36*11513SAlan.Adamson@Sun.COM static int intr_niumx_walk_step(mdb_walk_state_t *);
37909Segillett static void intr_pci_print_items(mdb_walk_state_t *);
38909Segillett static void intr_px_print_items(mdb_walk_state_t *);
391725Segillett static char *intr_get_intr_type(uint16_t type);
40909Segillett static void intr_print_banner(void);
41909Segillett
42909Segillett typedef struct intr_info {
43909Segillett uint32_t cpuid;
44909Segillett uint32_t inum;
45909Segillett uint32_t num;
46909Segillett uint32_t pil;
471725Segillett uint16_t intr_type;
48909Segillett uint16_t mondo;
49909Segillett uint8_t ino_ino;
50909Segillett uint_t intr_state;
51909Segillett int instance;
52909Segillett int shared;
53909Segillett char driver_name[12];
54909Segillett char pathname[MAXNAMELEN];
55909Segillett }
56909Segillett intr_info_t;
57909Segillett
583830Segillett #define PX_MAX_ENTRIES 32
593830Segillett
60909Segillett static void intr_print_elements(intr_info_t);
61909Segillett static int detailed = 0; /* Print detailed view */
62909Segillett
63909Segillett
64909Segillett static int
intr_walk_init(mdb_walk_state_t * wsp)65909Segillett intr_walk_init(mdb_walk_state_t *wsp)
66909Segillett {
67909Segillett wsp->walk_addr = NULL;
68909Segillett
69909Segillett return (WALK_NEXT);
70909Segillett }
71909Segillett
72909Segillett static int
intr_walk_step(mdb_walk_state_t * wsp)73909Segillett intr_walk_step(mdb_walk_state_t *wsp)
74909Segillett {
75909Segillett pci_t *pci_per_p;
76909Segillett px_t *px_state_p;
77*11513SAlan.Adamson@Sun.COM niumx_devstate_t *niumx_state_p;
78909Segillett
79909Segillett /* read globally declared structures in the pci driver */
80909Segillett if (mdb_readvar(&pci_per_p, "per_pci_state") != -1) {
81909Segillett wsp->walk_addr = (uintptr_t)pci_per_p;
82909Segillett intr_pci_walk_step(wsp);
83909Segillett }
84909Segillett
85909Segillett /* read globally declared structures in the px driver */
86909Segillett if (mdb_readvar(&px_state_p, "px_state_p") != -1) {
87909Segillett wsp->walk_addr = (uintptr_t)px_state_p;
88909Segillett intr_px_walk_step(wsp);
89909Segillett }
90909Segillett
91*11513SAlan.Adamson@Sun.COM /* read globally declared structures in the niumx driver */
92*11513SAlan.Adamson@Sun.COM if (mdb_readvar(&niumx_state_p, "niumx_state") != -1) {
93*11513SAlan.Adamson@Sun.COM wsp->walk_addr = (uintptr_t)niumx_state_p;
94*11513SAlan.Adamson@Sun.COM intr_niumx_walk_step(wsp);
95*11513SAlan.Adamson@Sun.COM }
96*11513SAlan.Adamson@Sun.COM
97909Segillett return (WALK_DONE);
98909Segillett }
99909Segillett
100909Segillett static int
intr_pci_walk_step(mdb_walk_state_t * wsp)101909Segillett intr_pci_walk_step(mdb_walk_state_t *wsp)
102909Segillett {
103909Segillett pci_t *pci_per_p;
104909Segillett pci_t pci_per;
105909Segillett uintptr_t start_addr;
106909Segillett
107909Segillett /* Read start of state structure array */
108909Segillett if (mdb_vread(&pci_per_p, sizeof (uintptr_t),
109909Segillett (uintptr_t)wsp->walk_addr) == -1) {
110909Segillett mdb_warn("intr: failed to read the initial pci_per_p "
111909Segillett "structure\n");
112909Segillett return (WALK_ERR);
113909Segillett }
114909Segillett
115909Segillett /* Figure out how many items are here */
116909Segillett start_addr = (uintptr_t)pci_per_p;
117909Segillett
118965Sgovinda intr_print_banner();
119965Sgovinda
120909Segillett while (mdb_vread(&pci_per_p, sizeof (uintptr_t),
121909Segillett (uintptr_t)start_addr) != -1) {
122909Segillett /* Read until nothing is left */
123909Segillett if (mdb_vread(&pci_per, sizeof (pci_t),
124909Segillett (uintptr_t)pci_per_p) == -1) {
125909Segillett return (WALK_DONE);
126909Segillett }
127909Segillett
128909Segillett wsp->walk_addr = (uintptr_t)pci_per.pci_ib_p;
129909Segillett intr_pci_print_items(wsp);
130909Segillett
131909Segillett start_addr += sizeof (uintptr_t);
132909Segillett }
133909Segillett
134909Segillett return (WALK_DONE);
135909Segillett }
136909Segillett
137909Segillett static int
intr_px_walk_step(mdb_walk_state_t * wsp)138909Segillett intr_px_walk_step(mdb_walk_state_t *wsp)
139909Segillett {
140909Segillett px_t *px_state_p;
141909Segillett px_t px_state;
142909Segillett uintptr_t start_addr;
1433830Segillett int x;
144909Segillett
145909Segillett /* Read start of state structure array */
146909Segillett if (mdb_vread(&px_state_p, sizeof (uintptr_t),
147909Segillett (uintptr_t)wsp->walk_addr) == -1) {
148909Segillett mdb_warn("intr: failed to read the initial px_per_p "
149909Segillett "structure\n");
150909Segillett return (WALK_ERR);
151909Segillett }
152909Segillett
153909Segillett /* Figure out how many items are here */
154909Segillett start_addr = (uintptr_t)px_state_p;
155909Segillett
156965Sgovinda intr_print_banner();
157965Sgovinda
1583830Segillett for (x = 0; x < PX_MAX_ENTRIES; x++) {
1593830Segillett (void) mdb_vread(&px_state_p, sizeof (uintptr_t),
1603830Segillett (uintptr_t)start_addr);
1613830Segillett
1623830Segillett start_addr += sizeof (uintptr_t);
1633830Segillett
1643830Segillett /* Read if anything is there */
165909Segillett if (mdb_vread(&px_state, sizeof (px_t),
166909Segillett (uintptr_t)px_state_p) == -1) {
1673830Segillett continue;
168909Segillett }
169909Segillett
170909Segillett wsp->walk_addr = (uintptr_t)px_state.px_ib_p;
171909Segillett intr_px_print_items(wsp);
172909Segillett }
173909Segillett
174909Segillett return (WALK_DONE);
175909Segillett }
176909Segillett
177*11513SAlan.Adamson@Sun.COM static int
intr_niumx_walk_step(mdb_walk_state_t * wsp)178*11513SAlan.Adamson@Sun.COM intr_niumx_walk_step(mdb_walk_state_t *wsp)
179*11513SAlan.Adamson@Sun.COM {
180*11513SAlan.Adamson@Sun.COM niumx_devstate_t *niumx_state_p;
181*11513SAlan.Adamson@Sun.COM niumx_devstate_t niumx_state;
182*11513SAlan.Adamson@Sun.COM uintptr_t start_addr;
183*11513SAlan.Adamson@Sun.COM char name[MODMAXNAMELEN + 1];
184*11513SAlan.Adamson@Sun.COM struct dev_info dev;
185*11513SAlan.Adamson@Sun.COM intr_info_t info;
186*11513SAlan.Adamson@Sun.COM int i;
187*11513SAlan.Adamson@Sun.COM
188*11513SAlan.Adamson@Sun.COM /* Read start of state structure array */
189*11513SAlan.Adamson@Sun.COM if (mdb_vread(&niumx_state_p, sizeof (uintptr_t),
190*11513SAlan.Adamson@Sun.COM (uintptr_t)wsp->walk_addr) == -1) {
191*11513SAlan.Adamson@Sun.COM mdb_warn("intr: failed to read the initial niumx_state_p "
192*11513SAlan.Adamson@Sun.COM "structure\n");
193*11513SAlan.Adamson@Sun.COM return (WALK_ERR);
194*11513SAlan.Adamson@Sun.COM }
195*11513SAlan.Adamson@Sun.COM
196*11513SAlan.Adamson@Sun.COM /* Figure out how many items are here */
197*11513SAlan.Adamson@Sun.COM start_addr = (uintptr_t)niumx_state_p;
198*11513SAlan.Adamson@Sun.COM
199*11513SAlan.Adamson@Sun.COM while (mdb_vread(&niumx_state_p, sizeof (uintptr_t),
200*11513SAlan.Adamson@Sun.COM (uintptr_t)start_addr) >= 0) {
201*11513SAlan.Adamson@Sun.COM
202*11513SAlan.Adamson@Sun.COM start_addr += sizeof (uintptr_t);
203*11513SAlan.Adamson@Sun.COM
204*11513SAlan.Adamson@Sun.COM /* Read if anything is there */
205*11513SAlan.Adamson@Sun.COM if (mdb_vread(&niumx_state, sizeof (niumx_devstate_t),
206*11513SAlan.Adamson@Sun.COM (uintptr_t)niumx_state_p) == -1) {
207*11513SAlan.Adamson@Sun.COM return (WALK_DONE);
208*11513SAlan.Adamson@Sun.COM }
209*11513SAlan.Adamson@Sun.COM
210*11513SAlan.Adamson@Sun.COM for (i = 0; i < NIUMX_MAX_INTRS; i++) {
211*11513SAlan.Adamson@Sun.COM if (niumx_state.niumx_ihtable[i].ih_sysino == 0)
212*11513SAlan.Adamson@Sun.COM continue;
213*11513SAlan.Adamson@Sun.COM
214*11513SAlan.Adamson@Sun.COM if (niumx_state.niumx_ihtable[i].ih_dip == 0)
215*11513SAlan.Adamson@Sun.COM continue;
216*11513SAlan.Adamson@Sun.COM
217*11513SAlan.Adamson@Sun.COM bzero((void *)&info, sizeof (intr_info_t));
218*11513SAlan.Adamson@Sun.COM
219*11513SAlan.Adamson@Sun.COM info.shared = 0;
220*11513SAlan.Adamson@Sun.COM
221*11513SAlan.Adamson@Sun.COM (void) mdb_devinfo2driver(
222*11513SAlan.Adamson@Sun.COM (uintptr_t)niumx_state.niumx_ihtable[i].ih_dip,
223*11513SAlan.Adamson@Sun.COM name, sizeof (name));
224*11513SAlan.Adamson@Sun.COM
225*11513SAlan.Adamson@Sun.COM (void) mdb_ddi_pathname(
226*11513SAlan.Adamson@Sun.COM (uintptr_t)niumx_state.niumx_ihtable[i].ih_dip,
227*11513SAlan.Adamson@Sun.COM info.pathname, sizeof (info.pathname));
228*11513SAlan.Adamson@Sun.COM
229*11513SAlan.Adamson@Sun.COM /* Get instance */
230*11513SAlan.Adamson@Sun.COM if (mdb_vread(&dev, sizeof (struct dev_info),
231*11513SAlan.Adamson@Sun.COM (uintptr_t)niumx_state.niumx_ihtable[i].ih_dip) ==
232*11513SAlan.Adamson@Sun.COM -1) {
233*11513SAlan.Adamson@Sun.COM mdb_warn("intr: failed to read DIP "
234*11513SAlan.Adamson@Sun.COM "structure\n");
235*11513SAlan.Adamson@Sun.COM
236*11513SAlan.Adamson@Sun.COM return (WALK_DONE);
237*11513SAlan.Adamson@Sun.COM }
238*11513SAlan.Adamson@Sun.COM
239*11513SAlan.Adamson@Sun.COM /* Make sure the name doesn't over run */
240*11513SAlan.Adamson@Sun.COM (void) mdb_snprintf(info.driver_name,
241*11513SAlan.Adamson@Sun.COM sizeof (info.driver_name), "%s", name);
242*11513SAlan.Adamson@Sun.COM
243*11513SAlan.Adamson@Sun.COM info.instance = dev.devi_instance;
244*11513SAlan.Adamson@Sun.COM info.inum = niumx_state.niumx_ihtable[i].ih_inum;
245*11513SAlan.Adamson@Sun.COM info.intr_type = DDI_INTR_TYPE_FIXED;
246*11513SAlan.Adamson@Sun.COM info.num = 0;
247*11513SAlan.Adamson@Sun.COM info.intr_state = niumx_state.niumx_ihtable[i].ih_state;
248*11513SAlan.Adamson@Sun.COM info.ino_ino = i;
249*11513SAlan.Adamson@Sun.COM info.mondo = niumx_state.niumx_ihtable[i].ih_sysino;
250*11513SAlan.Adamson@Sun.COM info.pil = niumx_state.niumx_ihtable[i].ih_pri;
251*11513SAlan.Adamson@Sun.COM info.cpuid = niumx_state.niumx_ihtable[i].ih_cpuid;
252*11513SAlan.Adamson@Sun.COM
253*11513SAlan.Adamson@Sun.COM intr_print_elements(info);
254*11513SAlan.Adamson@Sun.COM }
255*11513SAlan.Adamson@Sun.COM }
256*11513SAlan.Adamson@Sun.COM
257*11513SAlan.Adamson@Sun.COM return (WALK_DONE);
258*11513SAlan.Adamson@Sun.COM }
259*11513SAlan.Adamson@Sun.COM
260909Segillett static void
intr_pci_print_items(mdb_walk_state_t * wsp)261909Segillett intr_pci_print_items(mdb_walk_state_t *wsp)
262909Segillett {
2632973Sgovinda ib_t ib;
2642973Sgovinda ib_ino_info_t ino;
2652973Sgovinda ib_ino_pil_t ipil;
266909Segillett ih_t ih;
267909Segillett int count;
268909Segillett char name[MODMAXNAMELEN + 1];
2692973Sgovinda struct dev_info dev;
270909Segillett intr_info_t info;
271909Segillett
2722973Sgovinda if (mdb_vread(&ib, sizeof (ib_t),
273909Segillett (uintptr_t)wsp->walk_addr) == -1) {
274909Segillett mdb_warn("intr: failed to read pci interrupt block "
275909Segillett "structure\n");
276909Segillett return;
277909Segillett }
278909Segillett
279909Segillett /* Read in ib_ino_info_t structure at address */
2802973Sgovinda if (mdb_vread(&ino, sizeof (ib_ino_info_t),
2812973Sgovinda (uintptr_t)ib.ib_ino_lst) == -1) {
282909Segillett /* Nothing here to read from */
283909Segillett return;
284909Segillett }
285909Segillett
286909Segillett do {
2872973Sgovinda if (mdb_vread(&ipil, sizeof (ib_ino_pil_t),
2882973Sgovinda (uintptr_t)ino.ino_ipil_p) == -1) {
2892973Sgovinda mdb_warn("intr: failed to read pci interrupt "
2902973Sgovinda "ib_ino_pil_t structure\n");
291909Segillett return;
292909Segillett }
293909Segillett
294909Segillett do {
2952973Sgovinda if (mdb_vread(&ih, sizeof (ih_t),
2962973Sgovinda (uintptr_t)ipil.ipil_ih_start) == -1) {
2972973Sgovinda mdb_warn("intr: failed to read pci interrupt "
2982973Sgovinda "ih_t structure\n");
299909Segillett return;
300909Segillett }
301909Segillett
3022973Sgovinda count = 0;
3032973Sgovinda
3042973Sgovinda do {
3052973Sgovinda bzero((void *)&info, sizeof (intr_info_t));
3062973Sgovinda
3072973Sgovinda if ((ino.ino_ipil_size > 1) ||
3082973Sgovinda (ipil.ipil_ih_size > 1)) {
3092973Sgovinda info.shared = 1;
3102973Sgovinda }
3112973Sgovinda
3122973Sgovinda (void) mdb_devinfo2driver((uintptr_t)ih.ih_dip,
3132973Sgovinda name, sizeof (name));
3142973Sgovinda
3152973Sgovinda (void) mdb_ddi_pathname((uintptr_t)ih.ih_dip,
3162973Sgovinda info.pathname, sizeof (info.pathname));
3172973Sgovinda
3182973Sgovinda /* Get instance */
3192973Sgovinda if (mdb_vread(&dev, sizeof (struct dev_info),
3202973Sgovinda (uintptr_t)ih.ih_dip) == -1) {
3212973Sgovinda mdb_warn("intr: failed to read DIP "
3222973Sgovinda "structure\n");
3232973Sgovinda return;
3242973Sgovinda }
325909Segillett
3262973Sgovinda /* Make sure the name doesn't over run */
3272973Sgovinda (void) mdb_snprintf(info.driver_name,
3282973Sgovinda sizeof (info.driver_name), "%s", name);
3292973Sgovinda
3302973Sgovinda info.instance = dev.devi_instance;
3312973Sgovinda info.inum = ih.ih_inum;
3322973Sgovinda info.intr_type = DDI_INTR_TYPE_FIXED;
3332973Sgovinda info.num = 0;
3342973Sgovinda info.intr_state = ih.ih_intr_state;
3352973Sgovinda info.ino_ino = ino.ino_ino;
3362973Sgovinda info.mondo = ino.ino_mondo;
3372973Sgovinda info.pil = ipil.ipil_pil;
3382973Sgovinda info.cpuid = ino.ino_cpuid;
339909Segillett
3402973Sgovinda intr_print_elements(info);
3412973Sgovinda count++;
3422973Sgovinda
3432973Sgovinda (void) mdb_vread(&ih, sizeof (ih_t),
3442973Sgovinda (uintptr_t)ih.ih_next);
345909Segillett
3462973Sgovinda } while (count < ipil.ipil_ih_size);
347909Segillett
3482973Sgovinda } while (mdb_vread(&ipil, sizeof (ib_ino_pil_t),
3492973Sgovinda (uintptr_t)ipil.ipil_next_p) != -1);
350909Segillett
3512973Sgovinda } while (mdb_vread(&ino, sizeof (ib_ino_info_t),
3522973Sgovinda (uintptr_t)ino.ino_next_p) != -1);
353909Segillett }
354909Segillett
355909Segillett static void
intr_px_print_items(mdb_walk_state_t * wsp)356909Segillett intr_px_print_items(mdb_walk_state_t *wsp)
357909Segillett {
3582973Sgovinda px_ib_t ib;
3592973Sgovinda px_ino_t ino;
3602973Sgovinda px_ino_pil_t ipil;
3612973Sgovinda px_ih_t ih;
3622973Sgovinda int count;
3632973Sgovinda char name[MODMAXNAMELEN + 1];
3642973Sgovinda struct dev_info dev;
3652973Sgovinda intr_info_t info;
3662973Sgovinda devinfo_intr_t intr_p;
367909Segillett
3682973Sgovinda if (mdb_vread(&ib, sizeof (px_ib_t), wsp->walk_addr) == -1) {
369909Segillett return;
370909Segillett }
371909Segillett
3722973Sgovinda /* Read in px_ino_t structure at address */
3732973Sgovinda if (mdb_vread(&ino, sizeof (px_ino_t),
3742973Sgovinda (uintptr_t)ib.ib_ino_lst) == -1) {
375909Segillett /* Nothing here to read from */
376909Segillett return;
377909Segillett }
378909Segillett
3793830Segillett do { /* ino_next_p loop */
3802973Sgovinda if (mdb_vread(&ipil, sizeof (px_ino_pil_t),
3812973Sgovinda (uintptr_t)ino.ino_ipil_p) == -1) {
38210053SEvan.Yan@Sun.COM continue;
383909Segillett }
384909Segillett
3853830Segillett do { /* ipil_next_p loop */
3862973Sgovinda if (mdb_vread(&ih, sizeof (px_ih_t),
3872973Sgovinda (uintptr_t)ipil.ipil_ih_start) == -1) {
38810053SEvan.Yan@Sun.COM continue;
389909Segillett }
390909Segillett
3912973Sgovinda count = 0;
3922973Sgovinda
3933830Segillett do { /* ipil_ih_size loop */
3942973Sgovinda bzero((void *)&info, sizeof (intr_info_t));
395909Segillett
3962973Sgovinda (void) mdb_devinfo2driver((uintptr_t)ih.ih_dip,
3972973Sgovinda name, sizeof (name));
3982973Sgovinda
3992973Sgovinda (void) mdb_ddi_pathname((uintptr_t)ih.ih_dip,
4002973Sgovinda info.pathname, sizeof (info.pathname));
4011725Segillett
4022973Sgovinda /* Get instance */
4032973Sgovinda if (mdb_vread(&dev, sizeof (struct dev_info),
4042973Sgovinda (uintptr_t)ih.ih_dip) == -1) {
4052973Sgovinda mdb_warn("intr: failed to read DIP "
4062973Sgovinda "structure\n");
4072973Sgovinda return;
4082973Sgovinda }
4092973Sgovinda
4102973Sgovinda /* Make sure the name doesn't over run */
4112973Sgovinda (void) mdb_snprintf(info.driver_name,
4122973Sgovinda sizeof (info.driver_name), "%s", name);
4132973Sgovinda
4142973Sgovinda info.instance = dev.devi_instance;
4152973Sgovinda info.inum = ih.ih_inum;
4161725Segillett
4172973Sgovinda /*
4182973Sgovinda * Read the type used, keep PCIe messages
4192973Sgovinda * separate.
4202973Sgovinda */
4212973Sgovinda (void) mdb_vread(&intr_p,
4222973Sgovinda sizeof (devinfo_intr_t),
4232973Sgovinda (uintptr_t)dev.devi_intr_p);
4242973Sgovinda
4252973Sgovinda if (ih.ih_rec_type != MSG_REC) {
4262973Sgovinda info.intr_type =
4272973Sgovinda intr_p.devi_intr_curr_type;
4282973Sgovinda }
4292973Sgovinda
43010597SDaniel.Ice@Sun.COM if ((ino.ino_ipil_size > 1) ||
43110597SDaniel.Ice@Sun.COM (ipil.ipil_ih_size > 1)) {
4322973Sgovinda info.shared = 1;
4332973Sgovinda }
434909Segillett
4352973Sgovinda info.num = ih.ih_msg_code;
4362973Sgovinda info.intr_state = ih.ih_intr_state;
4372973Sgovinda info.ino_ino = ino.ino_ino;
4382973Sgovinda info.mondo = ino.ino_sysino;
4392973Sgovinda info.pil = ipil.ipil_pil;
4402973Sgovinda info.cpuid = ino.ino_cpuid;
4412973Sgovinda
4422973Sgovinda intr_print_elements(info);
4432973Sgovinda count++;
444909Segillett
4452973Sgovinda (void) mdb_vread(&ih, sizeof (px_ih_t),
4462973Sgovinda (uintptr_t)ih.ih_next);
4472973Sgovinda
4482973Sgovinda } while (count < ipil.ipil_ih_size);
449909Segillett
45010053SEvan.Yan@Sun.COM } while ((ipil.ipil_next_p != NULL) &&
45110053SEvan.Yan@Sun.COM (mdb_vread(&ipil, sizeof (px_ino_pil_t),
45210053SEvan.Yan@Sun.COM (uintptr_t)ipil.ipil_next_p) != -1));
453909Segillett
45410053SEvan.Yan@Sun.COM } while ((ino.ino_next_p != NULL) && (mdb_vread(&ino, sizeof (px_ino_t),
45510053SEvan.Yan@Sun.COM (uintptr_t)ino.ino_next_p) != -1));
456909Segillett }
457909Segillett
458909Segillett static char *
intr_get_intr_type(uint16_t type)4591725Segillett intr_get_intr_type(uint16_t type)
460909Segillett {
4611725Segillett switch (type) {
4621725Segillett case DDI_INTR_TYPE_FIXED:
4631725Segillett return ("Fixed");
4641725Segillett case DDI_INTR_TYPE_MSI:
4651725Segillett return ("MSI");
4661725Segillett case DDI_INTR_TYPE_MSIX:
4671725Segillett return ("MSI-X");
4681725Segillett default:
469909Segillett return ("PCIe");
470909Segillett }
471909Segillett }
472909Segillett
473909Segillett static void
intr_print_banner(void)474909Segillett intr_print_banner(void)
475909Segillett {
476909Segillett if (!detailed) {
477965Sgovinda mdb_printf("\n%<u>\tDevice\t"
478965Sgovinda " Type\t"
479965Sgovinda " MSG #\t"
480965Sgovinda " State\t"
481965Sgovinda " INO\t"
482965Sgovinda " Mondo\t"
48310597SDaniel.Ice@Sun.COM " Shared\t"
484965Sgovinda " Pil\t"
485965Sgovinda " CPU %</u>"
486965Sgovinda "\n");
487909Segillett }
488909Segillett }
489909Segillett
490909Segillett static void
intr_print_elements(intr_info_t info)491909Segillett intr_print_elements(intr_info_t info)
492909Segillett {
493909Segillett if (!detailed) {
494965Sgovinda mdb_printf(" %11s#%d\t", info.driver_name, info.instance);
495965Sgovinda mdb_printf(" %s\t", intr_get_intr_type(info.intr_type));
4961725Segillett if (info.intr_type == DDI_INTR_TYPE_FIXED) {
497965Sgovinda mdb_printf(" --- \t");
498909Segillett } else {
499965Sgovinda mdb_printf(" %4d\t", info.num);
500909Segillett }
501965Sgovinda mdb_printf(" %2s\t",
502909Segillett info.intr_state ? "enbl" : "disbl");
503965Sgovinda mdb_printf(" 0x%x\t", info.ino_ino);
504965Sgovinda mdb_printf(" 0x%x\t", info.mondo);
50510597SDaniel.Ice@Sun.COM mdb_printf(" %5s\t",
50610597SDaniel.Ice@Sun.COM info.shared ? "yes" : "no");
507965Sgovinda mdb_printf(" %4d\t", info.pil);
508965Sgovinda mdb_printf(" %3d \n", info.cpuid);
509909Segillett } else {
510909Segillett mdb_printf("\n-------------------------------------------\n");
511909Segillett mdb_printf("Device:\t\t%s\n", info.driver_name);
512909Segillett mdb_printf("Instance:\t%d\n", info.instance);
513909Segillett mdb_printf("Path:\t\t%s\n", info.pathname);
514909Segillett mdb_printf("Inum:\t\t%d\n", info.inum);
515909Segillett mdb_printf("Interrupt Type:\t%s\n",
516909Segillett intr_get_intr_type(info.intr_type));
5171725Segillett if (info.intr_type == DDI_INTR_TYPE_MSI) {
5181725Segillett mdb_printf("MSI Number:\t%d\n", info.num);
5191725Segillett } else if (info.intr_type == DDI_INTR_TYPE_MSIX) {
5201725Segillett mdb_printf("MSI-X Number:\t%d\n", info.num);
5211725Segillett } else if (!info.intr_type) {
5221725Segillett mdb_printf("PCIe Message #:\t%d\n", info.num);
5231725Segillett }
524909Segillett
525909Segillett mdb_printf("Shared Intr:\t%s\n",
526909Segillett info.shared ? "yes" : "no");
527909Segillett mdb_printf("State:\t\t%d (%s)\n", info.intr_state,
528909Segillett info.intr_state ? "Enabled" : "Disabled");
529909Segillett mdb_printf("INO:\t\t0x%x\n", info.ino_ino);
530909Segillett mdb_printf("Mondo:\t\t0x%x\n", info.mondo);
531909Segillett mdb_printf("Pil:\t\t%d\n", info.pil);
532909Segillett mdb_printf("CPU:\t\t%d\n", info.cpuid);
533909Segillett }
534909Segillett }
535909Segillett
536909Segillett /*ARGSUSED*/
537909Segillett static void
intr_walk_fini(mdb_walk_state_t * wsp)538909Segillett intr_walk_fini(mdb_walk_state_t *wsp)
539909Segillett {
540909Segillett /* Nothing to do here */
541909Segillett }
542909Segillett
543909Segillett /*ARGSUSED*/
544909Segillett static int
intr_intr(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)545909Segillett intr_intr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
546909Segillett {
547909Segillett detailed = 0;
548909Segillett
549909Segillett if (mdb_getopts(argc, argv, 'd', MDB_OPT_SETBITS, TRUE, &detailed,
550909Segillett NULL) != argc)
551909Segillett return (DCMD_USAGE);
552909Segillett
553909Segillett if (!(flags & DCMD_ADDRSPEC)) {
554909Segillett if (mdb_walk_dcmd("interrupts", "interrupts", argc, argv)
555909Segillett == -1) {
556909Segillett mdb_warn("can't walk pci/px buffer entries\n");
557909Segillett return (DCMD_ERR);
558909Segillett }
559909Segillett return (DCMD_OK);
560909Segillett }
561909Segillett
562909Segillett return (DCMD_OK);
563909Segillett }
564909Segillett
565909Segillett /*
566909Segillett * MDB module linkage information:
567909Segillett */
568909Segillett
569909Segillett static const mdb_dcmd_t dcmds[] = {
570909Segillett { "interrupts", "[-d]", "display the interrupt info registered with "
571909Segillett "the PCI/PX nexus drivers", intr_intr },
572909Segillett { NULL }
573909Segillett };
574909Segillett
575909Segillett static const mdb_walker_t walkers[] = {
576909Segillett { "interrupts", "walk PCI/PX interrupt structures",
577909Segillett intr_walk_init, intr_walk_step, intr_walk_fini },
578909Segillett { NULL }
579909Segillett };
580909Segillett
581909Segillett static const mdb_modinfo_t modinfo = {
582909Segillett MDB_API_VERSION, dcmds, walkers
583909Segillett };
584909Segillett
585909Segillett const mdb_modinfo_t *
_mdb_init(void)586909Segillett _mdb_init(void)
587909Segillett {
588909Segillett return (&modinfo);
589909Segillett }
590