1d7b41ca4Sanish /*
2d7b41ca4Sanish  * CDDL HEADER START
3d7b41ca4Sanish  *
4d7b41ca4Sanish  * The contents of this file are subject to the terms of the
5d7b41ca4Sanish  * Common Development and Distribution License (the "License").
6d7b41ca4Sanish  * You may not use this file except in compliance with the License.
7d7b41ca4Sanish  *
8d7b41ca4Sanish  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d7b41ca4Sanish  * or http://www.opensolaris.org/os/licensing.
10d7b41ca4Sanish  * See the License for the specific language governing permissions
11d7b41ca4Sanish  * and limitations under the License.
12d7b41ca4Sanish  *
13d7b41ca4Sanish  * When distributing Covered Code, include this CDDL HEADER in each
14d7b41ca4Sanish  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d7b41ca4Sanish  * If applicable, add the following below this CDDL HEADER, with the
16d7b41ca4Sanish  * fields enclosed by brackets "[]" replaced with your own identifying
17d7b41ca4Sanish  * information: Portions Copyright [yyyy] [name of copyright owner]
18d7b41ca4Sanish  *
19d7b41ca4Sanish  * CDDL HEADER END
20d7b41ca4Sanish  */
21d7b41ca4Sanish /*
225cd376e8SJimmy Vetayases  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23*1c2d0470SPatrick Mooney  * Copyright 2018 Joyent, Inc.
24d7b41ca4Sanish  */
25d7b41ca4Sanish 
26d7b41ca4Sanish #include "intr_common.h"
27d7b41ca4Sanish #include <sys/gld.h>
28d7b41ca4Sanish #include <sys/gldpriv.h>
29d7b41ca4Sanish 
30ae115bc7Smrj int		option_flags;
31ae115bc7Smrj uintptr_t	gld_intr_addr;
32*1c2d0470SPatrick Mooney int		apic_pir_vect;
33ae115bc7Smrj static struct av_head softvec_tbl[LOCK_LEVEL + 1];
34ae115bc7Smrj 
35ae115bc7Smrj static char *businfo_array[] = {
36ae115bc7Smrj 	" ",
37ae115bc7Smrj 	"CBUS",
38ae115bc7Smrj 	"CBUSII",
39ae115bc7Smrj 	"EISA",
40ae115bc7Smrj 	"FUTURE",
41ae115bc7Smrj 	"INTERN",
42ae115bc7Smrj 	"ISA",
43ae115bc7Smrj 	"MBI",
44ae115bc7Smrj 	"MBII",
45ae115bc7Smrj 	"PCIe",
46ae115bc7Smrj 	"MPI",
47ae115bc7Smrj 	"MPSA",
48ae115bc7Smrj 	"NUBUS",
49ae115bc7Smrj 	"PCI",
50ae115bc7Smrj 	"PCMCIA",
51ae115bc7Smrj 	"TC",
52ae115bc7Smrj 	"VL",
53ae115bc7Smrj 	"VME",
54ae115bc7Smrj 	"XPRESS",
55ae115bc7Smrj 	" "
56ae115bc7Smrj };
57d7b41ca4Sanish 
58d7b41ca4Sanish void
interrupt_help(void)59d7b41ca4Sanish interrupt_help(void)
60d7b41ca4Sanish {
61d7b41ca4Sanish 	mdb_printf("Prints the interrupt usage on the system.\n"
62d7b41ca4Sanish 	    "By default, only interrupt service routine names are printed.\n\n"
63d7b41ca4Sanish 	    "Switches:\n"
64d7b41ca4Sanish 	    "  -d   instead of ISR, print <driver_name><instance#>\n"
65d7b41ca4Sanish 	    "  -i   show like intrstat, cpu# ISR/<driver_name><instance#>\n");
66d7b41ca4Sanish }
67d7b41ca4Sanish 
68774ef820Sanish void
soft_interrupt_help(void)69774ef820Sanish soft_interrupt_help(void)
70774ef820Sanish {
71774ef820Sanish 	mdb_printf("Prints the soft interrupt usage on the system.\n"
72774ef820Sanish 	    "By default, only interrupt service routine names are printed.\n\n"
73774ef820Sanish 	    "Switch:\n"
74774ef820Sanish 	    "  -d   instead of ISR, print <driver_name><instance#>\n");
75774ef820Sanish }
76774ef820Sanish 
77774ef820Sanish /*
78774ef820Sanish  * This is copied from avintr.c
79774ef820Sanish  * NOTE: Ensure that this definition stays in sync
80774ef820Sanish  */
81774ef820Sanish typedef struct av_softinfo {
82774ef820Sanish 	cpuset_t	av_pending;	/* pending bitmasks */
83774ef820Sanish } av_softinfo_t;
84774ef820Sanish 
85774ef820Sanish /* ARGSUSED */
86774ef820Sanish int
soft_interrupt_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)87774ef820Sanish soft_interrupt_dump(uintptr_t addr, uint_t flags, int argc,
88774ef820Sanish     const mdb_arg_t *argv)
89774ef820Sanish {
90774ef820Sanish 	int			i;
91774ef820Sanish 	av_softinfo_t		avsoftinfo;
92774ef820Sanish 	struct autovec		avhp;
93774ef820Sanish 	ddi_softint_hdl_impl_t	hdlp;
94774ef820Sanish 
95774ef820Sanish 	option_flags = 0;
96774ef820Sanish 	if (mdb_getopts(argc, argv, 'd', MDB_OPT_SETBITS,
97774ef820Sanish 	    INTR_DISPLAY_DRVR_INST, &option_flags, NULL) != argc)
98774ef820Sanish 		return (DCMD_USAGE);
99774ef820Sanish 
100774ef820Sanish 	if (mdb_readvar(&softvec_tbl, "softvect") == -1) {
101774ef820Sanish 		mdb_warn("failed to read autovect");
102774ef820Sanish 		return (DCMD_ERR);
103774ef820Sanish 	}
104774ef820Sanish 
105774ef820Sanish 	/* Print the header first */
106774ef820Sanish 	mdb_printf("%<u>ADDR             PEND PIL ARG1             "
107774ef820Sanish 	    "ARG2            ISR(s)%</u>\n");
108774ef820Sanish 
109774ef820Sanish 	/* Walk all the entries */
110774ef820Sanish 	for (i = 0; i < LOCK_LEVEL + 1; i++) {
111774ef820Sanish 		/* Read the entry, if invalid continue */
112774ef820Sanish 		if (mdb_vread(&avhp, sizeof (struct autovec),
113774ef820Sanish 		    (uintptr_t)softvec_tbl[i].avh_link) == -1)
114774ef820Sanish 			continue;
115774ef820Sanish 
116774ef820Sanish 		do {
117774ef820Sanish 			if (!avhp.av_vector ||
118774ef820Sanish 			    (mdb_vread(&hdlp, sizeof (ddi_softint_hdl_impl_t),
119a563a037Sbholler 			    (uintptr_t)avhp.av_intr_id) == -1) ||
120774ef820Sanish 			    (mdb_vread(&avsoftinfo, sizeof (av_softinfo_t),
121a563a037Sbholler 			    (uintptr_t)hdlp.ih_pending) == -1))
122774ef820Sanish 				continue;
123774ef820Sanish 
124774ef820Sanish 			/* Print each soft interrupt entry */
125774ef820Sanish 			mdb_printf("%-16p %-2d   %-2d  %-16p %-16p",
126774ef820Sanish 			    avhp.av_intr_id, mdb_cpuset_find(
127a563a037Sbholler 			    (uintptr_t)&avsoftinfo.av_pending) != -1 ? 1 : 0,
128774ef820Sanish 			    avhp.av_prilevel, avhp.av_intarg1, avhp.av_intarg2);
129774ef820Sanish 			interrupt_print_isr((uintptr_t)avhp.av_vector,
130774ef820Sanish 			    (uintptr_t)avhp.av_intarg1, (uintptr_t)hdlp.ih_dip);
131774ef820Sanish 			mdb_printf("\n");
132774ef820Sanish 		} while (mdb_vread(&avhp, sizeof (struct autovec),
133774ef820Sanish 		    (uintptr_t)avhp.av_link) != -1);
134774ef820Sanish 	}
135774ef820Sanish 
136774ef820Sanish 	return (DCMD_OK);
137774ef820Sanish }
138ae115bc7Smrj 
139ae115bc7Smrj void
interrupt_print_isr(uintptr_t vector,uintptr_t arg1,uintptr_t dip)140ae115bc7Smrj interrupt_print_isr(uintptr_t vector, uintptr_t arg1, uintptr_t dip)
141ae115bc7Smrj {
142ae115bc7Smrj 	uintptr_t	isr_addr = vector;
143ae115bc7Smrj 	struct dev_info	dev_info;
144ae115bc7Smrj 
145ae115bc7Smrj 	/*
146ae115bc7Smrj 	 * figure out the real ISR function name from gld_intr()
147ae115bc7Smrj 	 */
148ae115bc7Smrj 	if (isr_addr == gld_intr_addr) {
149ae115bc7Smrj 		gld_mac_info_t 	macinfo;
150ae115bc7Smrj 
151ae115bc7Smrj 		if (mdb_vread(&macinfo, sizeof (gld_mac_info_t), arg1) != -1) {
152ae115bc7Smrj 			/* verify gld data structure and get the real ISR */
153ae115bc7Smrj 			if (macinfo.gldm_GLD_version == GLD_VERSION)
154ae115bc7Smrj 				isr_addr = (uintptr_t)macinfo.gldm_intr;
155ae115bc7Smrj 		}
156ae115bc7Smrj 	}
157ae115bc7Smrj 
158ae115bc7Smrj 	if ((option_flags & INTR_DISPLAY_DRVR_INST) && dip) {
159ae115bc7Smrj 		char drvr_name[MODMAXNAMELEN + 1];
160ae115bc7Smrj 
161ae115bc7Smrj 		if (dip && mdb_devinfo2driver(dip, drvr_name,
162ae115bc7Smrj 		    sizeof (drvr_name)) == 0) {
163ae115bc7Smrj 			(void) mdb_vread(&dev_info, sizeof (dev_info), dip);
164ae115bc7Smrj 			mdb_printf("%s#%d", drvr_name, dev_info.devi_instance);
165ae115bc7Smrj 		} else {
166ae115bc7Smrj 			mdb_printf("%a", isr_addr);
167ae115bc7Smrj 		}
168ae115bc7Smrj 
169ae115bc7Smrj 	} else {
170ae115bc7Smrj 		mdb_printf("%a", isr_addr);
171ae115bc7Smrj 	}
172ae115bc7Smrj }
173ae115bc7Smrj 
174ae115bc7Smrj /*
175ae115bc7Smrj  * get_interrupt_type:
176ae115bc7Smrj  *
177ae115bc7Smrj  *	Get some interrupt related useful information
178ae115bc7Smrj  *
179ae115bc7Smrj  *	NOTE: a0 is clock, c0/d0/e0 are x-calls, e1 is apic_error_intr
180ae115bc7Smrj  *	d1/d3 are cbe_fire interrupts
181ae115bc7Smrj  */
182ae115bc7Smrj static char *
get_interrupt_type(short index)183ae115bc7Smrj get_interrupt_type(short index)
184ae115bc7Smrj {
185ae115bc7Smrj 	if (index == RESERVE_INDEX)
186ae115bc7Smrj 		return ("IPI");
187ae115bc7Smrj 	else if (index == ACPI_INDEX)
188ae115bc7Smrj 		return ("Fixed");
189ae115bc7Smrj 	else if (index == MSI_INDEX)
190ae115bc7Smrj 		return ("MSI");
191ae115bc7Smrj 	else if (index == MSIX_INDEX)
192ae115bc7Smrj 		return ("MSI-X");
193ae115bc7Smrj 	else
194ae115bc7Smrj 		return ("Fixed");
195ae115bc7Smrj }
196ae115bc7Smrj 
1977ff178cdSJimmy Vetayases static char *
get_apix_interrupt_type(short type)1987ff178cdSJimmy Vetayases get_apix_interrupt_type(short type)
1997ff178cdSJimmy Vetayases {
2007ff178cdSJimmy Vetayases 	if (type == APIX_TYPE_IPI)
2017ff178cdSJimmy Vetayases 		return ("IPI");
2027ff178cdSJimmy Vetayases 	else if (type == APIX_TYPE_FIXED)
2037ff178cdSJimmy Vetayases 		return ("Fixed");
2047ff178cdSJimmy Vetayases 	else if (type == APIX_TYPE_MSI)
2057ff178cdSJimmy Vetayases 		return ("MSI");
2067ff178cdSJimmy Vetayases 	else if (type == APIX_TYPE_MSIX)
2077ff178cdSJimmy Vetayases 		return ("MSI-X");
2087ff178cdSJimmy Vetayases 	else
2097ff178cdSJimmy Vetayases 		return ("Fixed");
2107ff178cdSJimmy Vetayases }
2117ff178cdSJimmy Vetayases 
212ae115bc7Smrj void
apic_interrupt_dump(apic_irq_t * irqp,struct av_head * avp,int i,ushort_t * evtchnp,char level)213ae115bc7Smrj apic_interrupt_dump(apic_irq_t *irqp, struct av_head *avp,
214ae115bc7Smrj     int i, ushort_t *evtchnp, char level)
215ae115bc7Smrj {
216ae115bc7Smrj 	int		bus_type;
217ae115bc7Smrj 	int		j;
218ae115bc7Smrj 	char		*intr_type;
219ae115bc7Smrj 	char		ioapic_iline[10];
220ae115bc7Smrj 	char		ipl[3];
221ae115bc7Smrj 	char		cpu_assigned[4];
222ae115bc7Smrj 	char		evtchn[8];
223b6917abeSmishra 	uint32_t	assigned_cpu;
224ae115bc7Smrj 	struct autovec	avhp;
225ae115bc7Smrj 
226ae115bc7Smrj 	/* If invalid index; continue */
227ae115bc7Smrj 	if (!irqp->airq_mps_intr_index ||
228ae115bc7Smrj 	    irqp->airq_mps_intr_index == FREE_INDEX)
229ae115bc7Smrj 		return;
230ae115bc7Smrj 
231ae115bc7Smrj 	/* Figure out interrupt type and trigger information */
232ae115bc7Smrj 	intr_type = get_interrupt_type(irqp->airq_mps_intr_index);
233ae115bc7Smrj 
234ae115bc7Smrj 	/* Figure out IOAPIC number and ILINE number */
235ae115bc7Smrj 	if (APIC_IS_MSI_OR_MSIX_INDEX(irqp->airq_mps_intr_index))
236ae115bc7Smrj 		(void) mdb_snprintf(ioapic_iline, 10, "-    ");
237ae115bc7Smrj 	else {
238ae115bc7Smrj 		if (!irqp->airq_ioapicindex && !irqp->airq_intin_no) {
239ae115bc7Smrj 			if (strcmp(intr_type, "Fixed") == 0)
240ae115bc7Smrj 				(void) mdb_snprintf(ioapic_iline, 10,
241ae115bc7Smrj 				    "0x%x/0x%x", irqp->airq_ioapicindex,
242ae115bc7Smrj 				    irqp->airq_intin_no);
243ae115bc7Smrj 			else if (irqp->airq_mps_intr_index == RESERVE_INDEX)
244ae115bc7Smrj 				(void) mdb_snprintf(ioapic_iline, 10, "-    ");
245ae115bc7Smrj 			else
246ae115bc7Smrj 				(void) mdb_snprintf(ioapic_iline, 10, " ");
247ae115bc7Smrj 		} else
248ae115bc7Smrj 			(void) mdb_snprintf(ioapic_iline, 10, "0x%x/0x%x",
249ae115bc7Smrj 			    irqp->airq_ioapicindex, irqp->airq_intin_no);
250ae115bc7Smrj 	}
251ae115bc7Smrj 
252ae115bc7Smrj 	evtchn[0] = '\0';
253ae115bc7Smrj 	if (evtchnp != NULL)
254ae115bc7Smrj 		(void) mdb_snprintf(evtchn, 8, "%-7hd", *evtchnp);
255ae115bc7Smrj 
256ae115bc7Smrj 	assigned_cpu = irqp->airq_temp_cpu;
257ae115bc7Smrj 	if (assigned_cpu == IRQ_UNINIT || assigned_cpu == IRQ_UNBOUND)
258ae115bc7Smrj 		assigned_cpu = irqp->airq_cpu;
259ae115bc7Smrj 	bus_type = irqp->airq_iflag.bustype;
260ae115bc7Smrj 
261ae115bc7Smrj 	if (irqp->airq_mps_intr_index == RESERVE_INDEX) {
262ae115bc7Smrj 		(void) mdb_snprintf(cpu_assigned, 4, "all");
263ae115bc7Smrj 		(void) mdb_snprintf(ipl, 3, "%d", avp->avh_hi_pri);
264ae115bc7Smrj 	} else {
265ae115bc7Smrj 		(void) mdb_snprintf(cpu_assigned, 4, "%d", assigned_cpu);
266ae115bc7Smrj 		(void) mdb_snprintf(ipl, 3, "%d", irqp->airq_ipl);
267ae115bc7Smrj 	}
268ae115bc7Smrj 
269ae115bc7Smrj 	/* Print each interrupt entry */
270ae115bc7Smrj 	if (option_flags & INTR_DISPLAY_INTRSTAT)
271ae115bc7Smrj 		mdb_printf("%-4s", cpu_assigned);
272ae115bc7Smrj 	else
273ae115bc7Smrj 		mdb_printf("%-3d  0x%x %s%-3s %-6s %-3s %-6s %-4s%-3d   %-9s ",
274ae115bc7Smrj 		    i, irqp->airq_vector, evtchn, ipl,
275ae115bc7Smrj 		    (bus_type ? businfo_array[bus_type] : " "),
276ae115bc7Smrj 		    (level ? "Lvl" : "Edg"),
277ae115bc7Smrj 		    intr_type, cpu_assigned, irqp->airq_share, ioapic_iline);
278ae115bc7Smrj 
279ae115bc7Smrj 	/* If valid dip found; print driver name */
280ae115bc7Smrj 	if (irqp->airq_dip) {
281ae115bc7Smrj 		(void) mdb_vread(&avhp, sizeof (struct autovec),
282ae115bc7Smrj 		    (uintptr_t)avp->avh_link);
283ae115bc7Smrj 
284ae115bc7Smrj 		/*
285ae115bc7Smrj 		 * Loop thru all the shared IRQs
286ae115bc7Smrj 		 */
287ae115bc7Smrj 		if (irqp->airq_share)
288ae115bc7Smrj 			interrupt_print_isr((uintptr_t)avhp.av_vector,
289ae115bc7Smrj 			    (uintptr_t)avhp.av_intarg1, (uintptr_t)avhp.av_dip);
290ae115bc7Smrj 
291ae115bc7Smrj 		for (j = 1; irqp->airq_mps_intr_index != FREE_INDEX &&
292ae115bc7Smrj 		    j < irqp->airq_share; j++) {
293ae115bc7Smrj 			if (mdb_vread(&avhp, sizeof (struct autovec),
294ae115bc7Smrj 			    (uintptr_t)avhp.av_link) != -1) {
295ae115bc7Smrj 				mdb_printf(", ");
296ae115bc7Smrj 				interrupt_print_isr((uintptr_t)avhp.av_vector,
297ae115bc7Smrj 				    (uintptr_t)avhp.av_intarg1,
298ae115bc7Smrj 				    (uintptr_t)avhp.av_dip);
299ae115bc7Smrj 			} else {
300ae115bc7Smrj 				break;
301ae115bc7Smrj 			}
302ae115bc7Smrj 		}
303ae115bc7Smrj 
304ae115bc7Smrj 	} else {
305ae115bc7Smrj 		if (irqp->airq_mps_intr_index == RESERVE_INDEX &&
306*1c2d0470SPatrick Mooney 		    !irqp->airq_share) {
307*1c2d0470SPatrick Mooney 			if (irqp->airq_vector == apic_pir_vect) {
308*1c2d0470SPatrick Mooney 				mdb_printf("pir_ipi");
309*1c2d0470SPatrick Mooney 			} else {
310*1c2d0470SPatrick Mooney 				mdb_printf("poke_cpu");
311*1c2d0470SPatrick Mooney 			}
312*1c2d0470SPatrick Mooney 		} else if (mdb_vread(&avhp, sizeof (struct autovec),
313*1c2d0470SPatrick Mooney 		    (uintptr_t)avp->avh_link) != -1) {
314ae115bc7Smrj 			mdb_printf("%a", avhp.av_vector);
315*1c2d0470SPatrick Mooney 		}
316ae115bc7Smrj 	}
317ae115bc7Smrj 	mdb_printf("\n");
318ae115bc7Smrj }
3197ff178cdSJimmy Vetayases 
3207ff178cdSJimmy Vetayases void
apix_interrupt_dump(apix_vector_t * vectp,apic_irq_t * irqp,struct autovec * avp,ushort_t * evtchnp,char level)3217ff178cdSJimmy Vetayases apix_interrupt_dump(apix_vector_t *vectp, apic_irq_t *irqp,
3227ff178cdSJimmy Vetayases     struct autovec *avp, ushort_t *evtchnp, char level)
3237ff178cdSJimmy Vetayases {
3247ff178cdSJimmy Vetayases 	int		j;
3257ff178cdSJimmy Vetayases 	int		bus_type;
3267ff178cdSJimmy Vetayases 	char		*intr_type;
3277ff178cdSJimmy Vetayases 	char		irq[4];
3287ff178cdSJimmy Vetayases 	char		ioapic_iline[10];
3297ff178cdSJimmy Vetayases 	char		ipl[3];
3307ff178cdSJimmy Vetayases 	char		cpu_assigned[4];
3317ff178cdSJimmy Vetayases 	char		cpu_vector[10];
3327ff178cdSJimmy Vetayases 	char		evtchn[8];
3337ff178cdSJimmy Vetayases 
3347ff178cdSJimmy Vetayases 
3357ff178cdSJimmy Vetayases 	/* If invalid vector state; continue */
3367ff178cdSJimmy Vetayases 	if (vectp->v_state == APIX_STATE_FREED ||
3377ff178cdSJimmy Vetayases 	    vectp->v_state == APIX_STATE_OBSOLETED)
3387ff178cdSJimmy Vetayases 		return;
3397ff178cdSJimmy Vetayases 
3407ff178cdSJimmy Vetayases 	/* use apic_interrupt_ipi_dump for IPIs */
3417ff178cdSJimmy Vetayases 	if (vectp->v_type == APIX_TYPE_IPI)
3427ff178cdSJimmy Vetayases 		return;
3437ff178cdSJimmy Vetayases 
3447ff178cdSJimmy Vetayases 	/* Figure out interrupt type and trigger information */
3457ff178cdSJimmy Vetayases 	intr_type = get_apix_interrupt_type(vectp->v_type);
3467ff178cdSJimmy Vetayases 
3477ff178cdSJimmy Vetayases 	/* Figure out IOAPIC number and ILINE number */
3487ff178cdSJimmy Vetayases 	if (vectp->v_type != APIX_TYPE_FIXED) {
3497ff178cdSJimmy Vetayases 		level = 0; /* MSI/MSI-X are Edge trigger */
3507ff178cdSJimmy Vetayases 		(void) mdb_snprintf(irq, 4, "-   ");
3517ff178cdSJimmy Vetayases 		(void) mdb_snprintf(ioapic_iline, 10, "-    ");
3527ff178cdSJimmy Vetayases 		if (vectp->v_type == APIX_TYPE_IPI)
3537ff178cdSJimmy Vetayases 			bus_type = BUSTYPE_NONE;
3547ff178cdSJimmy Vetayases 		else
3557ff178cdSJimmy Vetayases 			/* statically assign MSI/X with "PCI" */
3567ff178cdSJimmy Vetayases 			bus_type = BUSTYPE_PCI;
3577ff178cdSJimmy Vetayases 	} else {
3587ff178cdSJimmy Vetayases 		(void) mdb_snprintf(irq, 4, "%d", vectp->v_inum);
3597ff178cdSJimmy Vetayases 		bus_type = irqp->airq_iflag.bustype;
3607ff178cdSJimmy Vetayases 		if (!irqp->airq_ioapicindex && !irqp->airq_intin_no) {
3617ff178cdSJimmy Vetayases 			if (strcmp(intr_type, "Fixed") == 0)
3627ff178cdSJimmy Vetayases 				(void) mdb_snprintf(ioapic_iline, 10,
3637ff178cdSJimmy Vetayases 				    "0x%x/0x%x", irqp->airq_ioapicindex,
3647ff178cdSJimmy Vetayases 				    irqp->airq_intin_no);
3657ff178cdSJimmy Vetayases 			else
3667ff178cdSJimmy Vetayases 				(void) mdb_snprintf(ioapic_iline, 10, "-    ");
3677ff178cdSJimmy Vetayases 		} else
3687ff178cdSJimmy Vetayases 			(void) mdb_snprintf(ioapic_iline, 10, "0x%x/0x%x",
3697ff178cdSJimmy Vetayases 			    irqp->airq_ioapicindex, irqp->airq_intin_no);
3707ff178cdSJimmy Vetayases 	}
3717ff178cdSJimmy Vetayases 
3727ff178cdSJimmy Vetayases 	evtchn[0] = '\0';
3737ff178cdSJimmy Vetayases 	if (evtchnp != NULL)
3747ff178cdSJimmy Vetayases 		(void) mdb_snprintf(evtchn, 8, "%-7hd", *evtchnp);
3757ff178cdSJimmy Vetayases 
3767ff178cdSJimmy Vetayases 	(void) mdb_snprintf(cpu_assigned, 4, "%d", vectp->v_cpuid);
3777ff178cdSJimmy Vetayases 	(void) mdb_snprintf(cpu_vector, 10, "%d/0x%x",
3787ff178cdSJimmy Vetayases 	    vectp->v_cpuid, vectp->v_vector);
3797ff178cdSJimmy Vetayases 
3807ff178cdSJimmy Vetayases 	/* Loop all the shared vectors */
3817ff178cdSJimmy Vetayases 	for (j = 0; j < vectp->v_share; ) {
3827ff178cdSJimmy Vetayases 		/* shared interrupts with one or more ISR removed afterwards */
3837ff178cdSJimmy Vetayases 		if (avp->av_vector == NULL) {
3847ff178cdSJimmy Vetayases 			if (mdb_vread(avp, sizeof (struct autovec),
3857ff178cdSJimmy Vetayases 			    (uintptr_t)avp->av_link) == -1)
3867ff178cdSJimmy Vetayases 				break;
3877ff178cdSJimmy Vetayases 			else
3887ff178cdSJimmy Vetayases 				continue;
3897ff178cdSJimmy Vetayases 		}
3907ff178cdSJimmy Vetayases 
3917ff178cdSJimmy Vetayases 		(void) mdb_snprintf(ipl, 3, "%d", avp->av_prilevel);
3927ff178cdSJimmy Vetayases 		/* Print each interrupt entry */
3937ff178cdSJimmy Vetayases 		if (option_flags & INTR_DISPLAY_INTRSTAT)
3947ff178cdSJimmy Vetayases 			mdb_printf("%-4s", cpu_assigned);
3957ff178cdSJimmy Vetayases 		else
3967ff178cdSJimmy Vetayases 			mdb_printf("%-9s %-3s %s%-3s %-6s %-3s %-6s %-3d   "
3977ff178cdSJimmy Vetayases 			    "%-9s ", cpu_vector, irq, evtchn, ipl,
3987ff178cdSJimmy Vetayases 			    (bus_type ? businfo_array[bus_type] : "-"),
3997ff178cdSJimmy Vetayases 			    (level ? "Lvl" : "Edg"),
4007ff178cdSJimmy Vetayases 			    intr_type, vectp->v_share, ioapic_iline);
4017ff178cdSJimmy Vetayases 
4027ff178cdSJimmy Vetayases 		interrupt_print_isr((uintptr_t)avp->av_vector,
4037ff178cdSJimmy Vetayases 		    (uintptr_t)avp->av_intarg1, (uintptr_t)avp->av_dip);
4047ff178cdSJimmy Vetayases 		mdb_printf("\n");
4057ff178cdSJimmy Vetayases 
4067ff178cdSJimmy Vetayases 		if (++j == vectp->v_share)
4077ff178cdSJimmy Vetayases 			break; /* done */
4087ff178cdSJimmy Vetayases 
4097ff178cdSJimmy Vetayases 		if (mdb_vread(avp, sizeof (struct autovec),
4107ff178cdSJimmy Vetayases 		    (uintptr_t)avp->av_link) == -1)
4117ff178cdSJimmy Vetayases 			break;
4127ff178cdSJimmy Vetayases 	}
4137ff178cdSJimmy Vetayases }
4147ff178cdSJimmy Vetayases 
4157ff178cdSJimmy Vetayases void
apix_interrupt_ipi_dump(apix_vector_t * vectp,struct autovec * avp,ushort_t * evtchnp)4167ff178cdSJimmy Vetayases apix_interrupt_ipi_dump(apix_vector_t *vectp, struct autovec *avp,
4177ff178cdSJimmy Vetayases     ushort_t *evtchnp)
4187ff178cdSJimmy Vetayases {
4197ff178cdSJimmy Vetayases 	char		*intr_type = "IPI";
4207ff178cdSJimmy Vetayases 	char		ioapic_iline[10];
4217ff178cdSJimmy Vetayases 	char		ipl[3];
4227ff178cdSJimmy Vetayases 	char		cpu_assigned[4];
4237ff178cdSJimmy Vetayases 	char		cpu_vector[10];
4247ff178cdSJimmy Vetayases 	char		evtchn[8];
4257ff178cdSJimmy Vetayases 
4267ff178cdSJimmy Vetayases 	/* If invalid vector state; continue */
4277ff178cdSJimmy Vetayases 	if (vectp->v_state == APIX_STATE_FREED ||
4287ff178cdSJimmy Vetayases 	    vectp->v_state == APIX_STATE_OBSOLETED)
4297ff178cdSJimmy Vetayases 		return;
4307ff178cdSJimmy Vetayases 
4317ff178cdSJimmy Vetayases 	if (vectp->v_type != APIX_TYPE_IPI)
4327ff178cdSJimmy Vetayases 		return;
4337ff178cdSJimmy Vetayases 
4347ff178cdSJimmy Vetayases 	/* No IOAPIC number and ILINE number info */
4357ff178cdSJimmy Vetayases 	(void) mdb_snprintf(ioapic_iline, 10, "-    ");
4367ff178cdSJimmy Vetayases 
4377ff178cdSJimmy Vetayases 	evtchn[0] = '\0';
4387ff178cdSJimmy Vetayases 	if (evtchnp != NULL)
4397ff178cdSJimmy Vetayases 		(void) mdb_snprintf(evtchn, 8, "%-7hd", *evtchnp);
4407ff178cdSJimmy Vetayases 
4417ff178cdSJimmy Vetayases 	/* IPI targeted ALL cpus */
4427ff178cdSJimmy Vetayases 	mdb_snprintf(cpu_assigned, 4, "all");
4437ff178cdSJimmy Vetayases 	(void) mdb_snprintf(cpu_vector, 10, "%s/0x%x",
4447ff178cdSJimmy Vetayases 	    "all", vectp->v_vector);
4457ff178cdSJimmy Vetayases 	/* IPI is not shared interrupt, so we can get the IPL from v_pri */
4467ff178cdSJimmy Vetayases 	(void) mdb_snprintf(ipl, 3, "%d", vectp->v_pri);
4477ff178cdSJimmy Vetayases 
4487ff178cdSJimmy Vetayases 	/* Print each interrupt entry */
4497ff178cdSJimmy Vetayases 	if (option_flags & INTR_DISPLAY_INTRSTAT)
4507ff178cdSJimmy Vetayases 		mdb_printf("%-4s", cpu_assigned);
4517ff178cdSJimmy Vetayases 	else
4527ff178cdSJimmy Vetayases 		mdb_printf("%-9s %-3s %s%-3s %-6s %-3s %-6s %-3d   %-9s ",
4537ff178cdSJimmy Vetayases 		    cpu_vector, "-  ", evtchn, ipl, "-   ", "Edg",
4547ff178cdSJimmy Vetayases 		    intr_type, vectp->v_share, ioapic_iline);
455*1c2d0470SPatrick Mooney 	if (!vectp->v_share) {
456*1c2d0470SPatrick Mooney 		if (vectp->v_vector == apic_pir_vect) {
457*1c2d0470SPatrick Mooney 			mdb_printf("pir_ipi");
458*1c2d0470SPatrick Mooney 		} else {
459*1c2d0470SPatrick Mooney 			mdb_printf("poke_cpu");
460*1c2d0470SPatrick Mooney 		}
461*1c2d0470SPatrick Mooney 	} else {
4627ff178cdSJimmy Vetayases 		mdb_printf("%a", avp->av_vector);
463*1c2d0470SPatrick Mooney 	}
4647ff178cdSJimmy Vetayases 
4657ff178cdSJimmy Vetayases 	mdb_printf("\n");
4667ff178cdSJimmy Vetayases }
467