13446Smrj /*
23446Smrj * CDDL HEADER START
33446Smrj *
43446Smrj * The contents of this file are subject to the terms of the
53446Smrj * Common Development and Distribution License (the "License").
63446Smrj * You may not use this file except in compliance with the License.
73446Smrj *
83446Smrj * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93446Smrj * or http://www.opensolaris.org/os/licensing.
103446Smrj * See the License for the specific language governing permissions
113446Smrj * and limitations under the License.
123446Smrj *
133446Smrj * When distributing Covered Code, include this CDDL HEADER in each
143446Smrj * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153446Smrj * If applicable, add the following below this CDDL HEADER, with the
163446Smrj * fields enclosed by brackets "[]" replaced with your own identifying
173446Smrj * information: Portions Copyright [yyyy] [name of copyright owner]
183446Smrj *
193446Smrj * CDDL HEADER END
203446Smrj */
213446Smrj /*
22*12825SJimmy.Vetayases@oracle.com * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
233446Smrj */
243446Smrj
253446Smrj #include "intr_common.h"
263446Smrj #include <sys/multidata.h>
273446Smrj #include <sys/gld.h>
283446Smrj #include <sys/gldpriv.h>
293446Smrj
303446Smrj int option_flags;
313446Smrj uintptr_t gld_intr_addr;
323446Smrj static struct av_head softvec_tbl[LOCK_LEVEL + 1];
333446Smrj
343446Smrj static char *businfo_array[] = {
353446Smrj " ",
363446Smrj "CBUS",
373446Smrj "CBUSII",
383446Smrj "EISA",
393446Smrj "FUTURE",
403446Smrj "INTERN",
413446Smrj "ISA",
423446Smrj "MBI",
433446Smrj "MBII",
443446Smrj "PCIe",
453446Smrj "MPI",
463446Smrj "MPSA",
473446Smrj "NUBUS",
483446Smrj "PCI",
493446Smrj "PCMCIA",
503446Smrj "TC",
513446Smrj "VL",
523446Smrj "VME",
533446Smrj "XPRESS",
543446Smrj " "
553446Smrj };
563446Smrj
573446Smrj void
interrupt_help(void)583446Smrj interrupt_help(void)
593446Smrj {
603446Smrj mdb_printf("Prints the interrupt usage on the system.\n"
613446Smrj "By default, only interrupt service routine names are printed.\n\n"
623446Smrj "Switches:\n"
633446Smrj " -d instead of ISR, print <driver_name><instance#>\n"
643446Smrj " -i show like intrstat, cpu# ISR/<driver_name><instance#>\n");
653446Smrj }
663446Smrj
673446Smrj void
soft_interrupt_help(void)683446Smrj soft_interrupt_help(void)
693446Smrj {
703446Smrj mdb_printf("Prints the soft interrupt usage on the system.\n"
713446Smrj "By default, only interrupt service routine names are printed.\n\n"
723446Smrj "Switch:\n"
733446Smrj " -d instead of ISR, print <driver_name><instance#>\n");
743446Smrj }
753446Smrj
763446Smrj /*
773446Smrj * This is copied from avintr.c
783446Smrj * NOTE: Ensure that this definition stays in sync
793446Smrj */
803446Smrj typedef struct av_softinfo {
813446Smrj cpuset_t av_pending; /* pending bitmasks */
823446Smrj } av_softinfo_t;
833446Smrj
843446Smrj /* ARGSUSED */
853446Smrj int
soft_interrupt_dump(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)863446Smrj soft_interrupt_dump(uintptr_t addr, uint_t flags, int argc,
873446Smrj const mdb_arg_t *argv)
883446Smrj {
893446Smrj int i;
903446Smrj av_softinfo_t avsoftinfo;
913446Smrj struct autovec avhp;
923446Smrj ddi_softint_hdl_impl_t hdlp;
933446Smrj
943446Smrj option_flags = 0;
953446Smrj if (mdb_getopts(argc, argv, 'd', MDB_OPT_SETBITS,
963446Smrj INTR_DISPLAY_DRVR_INST, &option_flags, NULL) != argc)
973446Smrj return (DCMD_USAGE);
983446Smrj
993446Smrj if (mdb_readvar(&softvec_tbl, "softvect") == -1) {
1003446Smrj mdb_warn("failed to read autovect");
1013446Smrj return (DCMD_ERR);
1023446Smrj }
1033446Smrj
1043446Smrj /* Print the header first */
1053446Smrj mdb_printf("%<u>ADDR PEND PIL ARG1 "
1063446Smrj "ARG2 ISR(s)%</u>\n");
1073446Smrj
1083446Smrj /* Walk all the entries */
1093446Smrj for (i = 0; i < LOCK_LEVEL + 1; i++) {
1103446Smrj /* Read the entry, if invalid continue */
1113446Smrj if (mdb_vread(&avhp, sizeof (struct autovec),
1123446Smrj (uintptr_t)softvec_tbl[i].avh_link) == -1)
1133446Smrj continue;
1143446Smrj
1153446Smrj do {
1163446Smrj if (!avhp.av_vector ||
1173446Smrj (mdb_vread(&hdlp, sizeof (ddi_softint_hdl_impl_t),
1186336Sbholler (uintptr_t)avhp.av_intr_id) == -1) ||
1193446Smrj (mdb_vread(&avsoftinfo, sizeof (av_softinfo_t),
1206336Sbholler (uintptr_t)hdlp.ih_pending) == -1))
1213446Smrj continue;
1223446Smrj
1233446Smrj /* Print each soft interrupt entry */
1243446Smrj mdb_printf("%-16p %-2d %-2d %-16p %-16p",
1253446Smrj avhp.av_intr_id, mdb_cpuset_find(
1266336Sbholler (uintptr_t)&avsoftinfo.av_pending) != -1 ? 1 : 0,
1273446Smrj avhp.av_prilevel, avhp.av_intarg1, avhp.av_intarg2);
1283446Smrj interrupt_print_isr((uintptr_t)avhp.av_vector,
1293446Smrj (uintptr_t)avhp.av_intarg1, (uintptr_t)hdlp.ih_dip);
1303446Smrj mdb_printf("\n");
1313446Smrj } while (mdb_vread(&avhp, sizeof (struct autovec),
1323446Smrj (uintptr_t)avhp.av_link) != -1);
1333446Smrj }
1343446Smrj
1353446Smrj return (DCMD_OK);
1363446Smrj }
1373446Smrj
1383446Smrj void
interrupt_print_isr(uintptr_t vector,uintptr_t arg1,uintptr_t dip)1393446Smrj interrupt_print_isr(uintptr_t vector, uintptr_t arg1, uintptr_t dip)
1403446Smrj {
1413446Smrj uintptr_t isr_addr = vector;
1423446Smrj struct dev_info dev_info;
1433446Smrj
1443446Smrj /*
1453446Smrj * figure out the real ISR function name from gld_intr()
1463446Smrj */
1473446Smrj if (isr_addr == gld_intr_addr) {
1483446Smrj gld_mac_info_t macinfo;
1493446Smrj
1503446Smrj if (mdb_vread(&macinfo, sizeof (gld_mac_info_t), arg1) != -1) {
1513446Smrj /* verify gld data structure and get the real ISR */
1523446Smrj if (macinfo.gldm_GLD_version == GLD_VERSION)
1533446Smrj isr_addr = (uintptr_t)macinfo.gldm_intr;
1543446Smrj }
1553446Smrj }
1563446Smrj
1573446Smrj if ((option_flags & INTR_DISPLAY_DRVR_INST) && dip) {
1583446Smrj char drvr_name[MODMAXNAMELEN + 1];
1593446Smrj
1603446Smrj if (dip && mdb_devinfo2driver(dip, drvr_name,
1613446Smrj sizeof (drvr_name)) == 0) {
1623446Smrj (void) mdb_vread(&dev_info, sizeof (dev_info), dip);
1633446Smrj mdb_printf("%s#%d", drvr_name, dev_info.devi_instance);
1643446Smrj } else {
1653446Smrj mdb_printf("%a", isr_addr);
1663446Smrj }
1673446Smrj
1683446Smrj } else {
1693446Smrj mdb_printf("%a", isr_addr);
1703446Smrj }
1713446Smrj }
1723446Smrj
1733446Smrj /*
1743446Smrj * get_interrupt_type:
1753446Smrj *
1763446Smrj * Get some interrupt related useful information
1773446Smrj *
1783446Smrj * NOTE: a0 is clock, c0/d0/e0 are x-calls, e1 is apic_error_intr
1793446Smrj * d1/d3 are cbe_fire interrupts
1803446Smrj */
1813446Smrj static char *
get_interrupt_type(short index)1823446Smrj get_interrupt_type(short index)
1833446Smrj {
1843446Smrj if (index == RESERVE_INDEX)
1853446Smrj return ("IPI");
1863446Smrj else if (index == ACPI_INDEX)
1873446Smrj return ("Fixed");
1883446Smrj else if (index == MSI_INDEX)
1893446Smrj return ("MSI");
1903446Smrj else if (index == MSIX_INDEX)
1913446Smrj return ("MSI-X");
1923446Smrj else
1933446Smrj return ("Fixed");
1943446Smrj }
1953446Smrj
19612683SJimmy.Vetayases@oracle.com static char *
get_apix_interrupt_type(short type)19712683SJimmy.Vetayases@oracle.com get_apix_interrupt_type(short type)
19812683SJimmy.Vetayases@oracle.com {
19912683SJimmy.Vetayases@oracle.com if (type == APIX_TYPE_IPI)
20012683SJimmy.Vetayases@oracle.com return ("IPI");
20112683SJimmy.Vetayases@oracle.com else if (type == APIX_TYPE_FIXED)
20212683SJimmy.Vetayases@oracle.com return ("Fixed");
20312683SJimmy.Vetayases@oracle.com else if (type == APIX_TYPE_MSI)
20412683SJimmy.Vetayases@oracle.com return ("MSI");
20512683SJimmy.Vetayases@oracle.com else if (type == APIX_TYPE_MSIX)
20612683SJimmy.Vetayases@oracle.com return ("MSI-X");
20712683SJimmy.Vetayases@oracle.com else
20812683SJimmy.Vetayases@oracle.com return ("Fixed");
20912683SJimmy.Vetayases@oracle.com }
21012683SJimmy.Vetayases@oracle.com
2113446Smrj void
apic_interrupt_dump(apic_irq_t * irqp,struct av_head * avp,int i,ushort_t * evtchnp,char level)2123446Smrj apic_interrupt_dump(apic_irq_t *irqp, struct av_head *avp,
2133446Smrj int i, ushort_t *evtchnp, char level)
2143446Smrj {
2153446Smrj int bus_type;
2163446Smrj int j;
2173446Smrj char *intr_type;
2183446Smrj char ioapic_iline[10];
2193446Smrj char ipl[3];
2203446Smrj char cpu_assigned[4];
2213446Smrj char evtchn[8];
2227282Smishra uint32_t assigned_cpu;
2233446Smrj struct autovec avhp;
2243446Smrj
2253446Smrj /* If invalid index; continue */
2263446Smrj if (!irqp->airq_mps_intr_index ||
2273446Smrj irqp->airq_mps_intr_index == FREE_INDEX)
2283446Smrj return;
2293446Smrj
2303446Smrj /* Figure out interrupt type and trigger information */
2313446Smrj intr_type = get_interrupt_type(irqp->airq_mps_intr_index);
2323446Smrj
2333446Smrj /* Figure out IOAPIC number and ILINE number */
2343446Smrj if (APIC_IS_MSI_OR_MSIX_INDEX(irqp->airq_mps_intr_index))
2353446Smrj (void) mdb_snprintf(ioapic_iline, 10, "- ");
2363446Smrj else {
2373446Smrj if (!irqp->airq_ioapicindex && !irqp->airq_intin_no) {
2383446Smrj if (strcmp(intr_type, "Fixed") == 0)
2393446Smrj (void) mdb_snprintf(ioapic_iline, 10,
2403446Smrj "0x%x/0x%x", irqp->airq_ioapicindex,
2413446Smrj irqp->airq_intin_no);
2423446Smrj else if (irqp->airq_mps_intr_index == RESERVE_INDEX)
2433446Smrj (void) mdb_snprintf(ioapic_iline, 10, "- ");
2443446Smrj else
2453446Smrj (void) mdb_snprintf(ioapic_iline, 10, " ");
2463446Smrj } else
2473446Smrj (void) mdb_snprintf(ioapic_iline, 10, "0x%x/0x%x",
2483446Smrj irqp->airq_ioapicindex, irqp->airq_intin_no);
2493446Smrj }
2503446Smrj
2513446Smrj evtchn[0] = '\0';
2523446Smrj if (evtchnp != NULL)
2533446Smrj (void) mdb_snprintf(evtchn, 8, "%-7hd", *evtchnp);
2543446Smrj
2553446Smrj assigned_cpu = irqp->airq_temp_cpu;
2563446Smrj if (assigned_cpu == IRQ_UNINIT || assigned_cpu == IRQ_UNBOUND)
2573446Smrj assigned_cpu = irqp->airq_cpu;
2583446Smrj bus_type = irqp->airq_iflag.bustype;
2593446Smrj
2603446Smrj if (irqp->airq_mps_intr_index == RESERVE_INDEX) {
2613446Smrj (void) mdb_snprintf(cpu_assigned, 4, "all");
2623446Smrj (void) mdb_snprintf(ipl, 3, "%d", avp->avh_hi_pri);
2633446Smrj } else {
2643446Smrj (void) mdb_snprintf(cpu_assigned, 4, "%d", assigned_cpu);
2653446Smrj (void) mdb_snprintf(ipl, 3, "%d", irqp->airq_ipl);
2663446Smrj }
2673446Smrj
2683446Smrj /* Print each interrupt entry */
2693446Smrj if (option_flags & INTR_DISPLAY_INTRSTAT)
2703446Smrj mdb_printf("%-4s", cpu_assigned);
2713446Smrj else
2723446Smrj mdb_printf("%-3d 0x%x %s%-3s %-6s %-3s %-6s %-4s%-3d %-9s ",
2733446Smrj i, irqp->airq_vector, evtchn, ipl,
2743446Smrj (bus_type ? businfo_array[bus_type] : " "),
2753446Smrj (level ? "Lvl" : "Edg"),
2763446Smrj intr_type, cpu_assigned, irqp->airq_share, ioapic_iline);
2773446Smrj
2783446Smrj /* If valid dip found; print driver name */
2793446Smrj if (irqp->airq_dip) {
2803446Smrj (void) mdb_vread(&avhp, sizeof (struct autovec),
2813446Smrj (uintptr_t)avp->avh_link);
2823446Smrj
2833446Smrj /*
2843446Smrj * Loop thru all the shared IRQs
2853446Smrj */
2863446Smrj if (irqp->airq_share)
2873446Smrj interrupt_print_isr((uintptr_t)avhp.av_vector,
2883446Smrj (uintptr_t)avhp.av_intarg1, (uintptr_t)avhp.av_dip);
2893446Smrj
2903446Smrj for (j = 1; irqp->airq_mps_intr_index != FREE_INDEX &&
2913446Smrj j < irqp->airq_share; j++) {
2923446Smrj if (mdb_vread(&avhp, sizeof (struct autovec),
2933446Smrj (uintptr_t)avhp.av_link) != -1) {
2943446Smrj mdb_printf(", ");
2953446Smrj interrupt_print_isr((uintptr_t)avhp.av_vector,
2963446Smrj (uintptr_t)avhp.av_intarg1,
2973446Smrj (uintptr_t)avhp.av_dip);
2983446Smrj } else {
2993446Smrj break;
3003446Smrj }
3013446Smrj }
3023446Smrj
3033446Smrj } else {
3043446Smrj if (irqp->airq_mps_intr_index == RESERVE_INDEX &&
3053446Smrj !irqp->airq_share)
3063446Smrj mdb_printf("poke_cpu");
3073446Smrj else if (mdb_vread(&avhp, sizeof (struct autovec),
3083446Smrj (uintptr_t)avp->avh_link) != -1)
3093446Smrj mdb_printf("%a", avhp.av_vector);
3103446Smrj }
3113446Smrj mdb_printf("\n");
3123446Smrj }
31312683SJimmy.Vetayases@oracle.com
31412683SJimmy.Vetayases@oracle.com void
apix_interrupt_dump(apix_vector_t * vectp,apic_irq_t * irqp,struct autovec * avp,ushort_t * evtchnp,char level)31512683SJimmy.Vetayases@oracle.com apix_interrupt_dump(apix_vector_t *vectp, apic_irq_t *irqp,
31612683SJimmy.Vetayases@oracle.com struct autovec *avp, ushort_t *evtchnp, char level)
31712683SJimmy.Vetayases@oracle.com {
31812683SJimmy.Vetayases@oracle.com int j;
31912683SJimmy.Vetayases@oracle.com int bus_type;
32012683SJimmy.Vetayases@oracle.com char *intr_type;
32112683SJimmy.Vetayases@oracle.com char irq[4];
32212683SJimmy.Vetayases@oracle.com char ioapic_iline[10];
32312683SJimmy.Vetayases@oracle.com char ipl[3];
32412683SJimmy.Vetayases@oracle.com char cpu_assigned[4];
32512683SJimmy.Vetayases@oracle.com char cpu_vector[10];
32612683SJimmy.Vetayases@oracle.com char evtchn[8];
32712683SJimmy.Vetayases@oracle.com
32812683SJimmy.Vetayases@oracle.com
32912683SJimmy.Vetayases@oracle.com /* If invalid vector state; continue */
33012683SJimmy.Vetayases@oracle.com if (vectp->v_state == APIX_STATE_FREED ||
33112683SJimmy.Vetayases@oracle.com vectp->v_state == APIX_STATE_OBSOLETED)
33212683SJimmy.Vetayases@oracle.com return;
33312683SJimmy.Vetayases@oracle.com
33412683SJimmy.Vetayases@oracle.com /* use apic_interrupt_ipi_dump for IPIs */
33512683SJimmy.Vetayases@oracle.com if (vectp->v_type == APIX_TYPE_IPI)
33612683SJimmy.Vetayases@oracle.com return;
33712683SJimmy.Vetayases@oracle.com
33812683SJimmy.Vetayases@oracle.com /* Figure out interrupt type and trigger information */
33912683SJimmy.Vetayases@oracle.com intr_type = get_apix_interrupt_type(vectp->v_type);
34012683SJimmy.Vetayases@oracle.com
34112683SJimmy.Vetayases@oracle.com /* Figure out IOAPIC number and ILINE number */
34212683SJimmy.Vetayases@oracle.com if (vectp->v_type != APIX_TYPE_FIXED) {
34312683SJimmy.Vetayases@oracle.com level = 0; /* MSI/MSI-X are Edge trigger */
34412683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(irq, 4, "- ");
34512683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(ioapic_iline, 10, "- ");
34612683SJimmy.Vetayases@oracle.com if (vectp->v_type == APIX_TYPE_IPI)
34712683SJimmy.Vetayases@oracle.com bus_type = BUSTYPE_NONE;
34812683SJimmy.Vetayases@oracle.com else
34912683SJimmy.Vetayases@oracle.com /* statically assign MSI/X with "PCI" */
35012683SJimmy.Vetayases@oracle.com bus_type = BUSTYPE_PCI;
35112683SJimmy.Vetayases@oracle.com } else {
35212683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(irq, 4, "%d", vectp->v_inum);
35312683SJimmy.Vetayases@oracle.com bus_type = irqp->airq_iflag.bustype;
35412683SJimmy.Vetayases@oracle.com if (!irqp->airq_ioapicindex && !irqp->airq_intin_no) {
35512683SJimmy.Vetayases@oracle.com if (strcmp(intr_type, "Fixed") == 0)
35612683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(ioapic_iline, 10,
35712683SJimmy.Vetayases@oracle.com "0x%x/0x%x", irqp->airq_ioapicindex,
35812683SJimmy.Vetayases@oracle.com irqp->airq_intin_no);
35912683SJimmy.Vetayases@oracle.com else
36012683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(ioapic_iline, 10, "- ");
36112683SJimmy.Vetayases@oracle.com } else
36212683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(ioapic_iline, 10, "0x%x/0x%x",
36312683SJimmy.Vetayases@oracle.com irqp->airq_ioapicindex, irqp->airq_intin_no);
36412683SJimmy.Vetayases@oracle.com }
36512683SJimmy.Vetayases@oracle.com
36612683SJimmy.Vetayases@oracle.com evtchn[0] = '\0';
36712683SJimmy.Vetayases@oracle.com if (evtchnp != NULL)
36812683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(evtchn, 8, "%-7hd", *evtchnp);
36912683SJimmy.Vetayases@oracle.com
37012683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(cpu_assigned, 4, "%d", vectp->v_cpuid);
37112683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(cpu_vector, 10, "%d/0x%x",
37212683SJimmy.Vetayases@oracle.com vectp->v_cpuid, vectp->v_vector);
37312683SJimmy.Vetayases@oracle.com
37412683SJimmy.Vetayases@oracle.com /* Loop all the shared vectors */
37512683SJimmy.Vetayases@oracle.com for (j = 0; j < vectp->v_share; ) {
37612683SJimmy.Vetayases@oracle.com /* shared interrupts with one or more ISR removed afterwards */
37712683SJimmy.Vetayases@oracle.com if (avp->av_vector == NULL) {
37812683SJimmy.Vetayases@oracle.com if (mdb_vread(avp, sizeof (struct autovec),
37912683SJimmy.Vetayases@oracle.com (uintptr_t)avp->av_link) == -1)
38012683SJimmy.Vetayases@oracle.com break;
38112683SJimmy.Vetayases@oracle.com else
38212683SJimmy.Vetayases@oracle.com continue;
38312683SJimmy.Vetayases@oracle.com }
38412683SJimmy.Vetayases@oracle.com
38512683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(ipl, 3, "%d", avp->av_prilevel);
38612683SJimmy.Vetayases@oracle.com /* Print each interrupt entry */
38712683SJimmy.Vetayases@oracle.com if (option_flags & INTR_DISPLAY_INTRSTAT)
38812683SJimmy.Vetayases@oracle.com mdb_printf("%-4s", cpu_assigned);
38912683SJimmy.Vetayases@oracle.com else
39012683SJimmy.Vetayases@oracle.com mdb_printf("%-9s %-3s %s%-3s %-6s %-3s %-6s %-3d "
39112683SJimmy.Vetayases@oracle.com "%-9s ", cpu_vector, irq, evtchn, ipl,
39212683SJimmy.Vetayases@oracle.com (bus_type ? businfo_array[bus_type] : "-"),
39312683SJimmy.Vetayases@oracle.com (level ? "Lvl" : "Edg"),
39412683SJimmy.Vetayases@oracle.com intr_type, vectp->v_share, ioapic_iline);
39512683SJimmy.Vetayases@oracle.com
39612683SJimmy.Vetayases@oracle.com interrupt_print_isr((uintptr_t)avp->av_vector,
39712683SJimmy.Vetayases@oracle.com (uintptr_t)avp->av_intarg1, (uintptr_t)avp->av_dip);
39812683SJimmy.Vetayases@oracle.com mdb_printf("\n");
39912683SJimmy.Vetayases@oracle.com
40012683SJimmy.Vetayases@oracle.com if (++j == vectp->v_share)
40112683SJimmy.Vetayases@oracle.com break; /* done */
40212683SJimmy.Vetayases@oracle.com
40312683SJimmy.Vetayases@oracle.com if (mdb_vread(avp, sizeof (struct autovec),
40412683SJimmy.Vetayases@oracle.com (uintptr_t)avp->av_link) == -1)
40512683SJimmy.Vetayases@oracle.com break;
40612683SJimmy.Vetayases@oracle.com }
40712683SJimmy.Vetayases@oracle.com }
40812683SJimmy.Vetayases@oracle.com
40912683SJimmy.Vetayases@oracle.com void
apix_interrupt_ipi_dump(apix_vector_t * vectp,struct autovec * avp,ushort_t * evtchnp)41012683SJimmy.Vetayases@oracle.com apix_interrupt_ipi_dump(apix_vector_t *vectp, struct autovec *avp,
41112683SJimmy.Vetayases@oracle.com ushort_t *evtchnp)
41212683SJimmy.Vetayases@oracle.com {
41312683SJimmy.Vetayases@oracle.com char *intr_type = "IPI";
41412683SJimmy.Vetayases@oracle.com char ioapic_iline[10];
41512683SJimmy.Vetayases@oracle.com char ipl[3];
41612683SJimmy.Vetayases@oracle.com char cpu_assigned[4];
41712683SJimmy.Vetayases@oracle.com char cpu_vector[10];
41812683SJimmy.Vetayases@oracle.com char evtchn[8];
41912683SJimmy.Vetayases@oracle.com
42012683SJimmy.Vetayases@oracle.com /* If invalid vector state; continue */
42112683SJimmy.Vetayases@oracle.com if (vectp->v_state == APIX_STATE_FREED ||
42212683SJimmy.Vetayases@oracle.com vectp->v_state == APIX_STATE_OBSOLETED)
42312683SJimmy.Vetayases@oracle.com return;
42412683SJimmy.Vetayases@oracle.com
42512683SJimmy.Vetayases@oracle.com if (vectp->v_type != APIX_TYPE_IPI)
42612683SJimmy.Vetayases@oracle.com return;
42712683SJimmy.Vetayases@oracle.com
42812683SJimmy.Vetayases@oracle.com /* No IOAPIC number and ILINE number info */
42912683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(ioapic_iline, 10, "- ");
43012683SJimmy.Vetayases@oracle.com
43112683SJimmy.Vetayases@oracle.com evtchn[0] = '\0';
43212683SJimmy.Vetayases@oracle.com if (evtchnp != NULL)
43312683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(evtchn, 8, "%-7hd", *evtchnp);
43412683SJimmy.Vetayases@oracle.com
43512683SJimmy.Vetayases@oracle.com /* IPI targeted ALL cpus */
43612683SJimmy.Vetayases@oracle.com mdb_snprintf(cpu_assigned, 4, "all");
43712683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(cpu_vector, 10, "%s/0x%x",
43812683SJimmy.Vetayases@oracle.com "all", vectp->v_vector);
43912683SJimmy.Vetayases@oracle.com /* IPI is not shared interrupt, so we can get the IPL from v_pri */
44012683SJimmy.Vetayases@oracle.com (void) mdb_snprintf(ipl, 3, "%d", vectp->v_pri);
44112683SJimmy.Vetayases@oracle.com
44212683SJimmy.Vetayases@oracle.com /* Print each interrupt entry */
44312683SJimmy.Vetayases@oracle.com if (option_flags & INTR_DISPLAY_INTRSTAT)
44412683SJimmy.Vetayases@oracle.com mdb_printf("%-4s", cpu_assigned);
44512683SJimmy.Vetayases@oracle.com else
44612683SJimmy.Vetayases@oracle.com mdb_printf("%-9s %-3s %s%-3s %-6s %-3s %-6s %-3d %-9s ",
44712683SJimmy.Vetayases@oracle.com cpu_vector, "- ", evtchn, ipl, "- ", "Edg",
44812683SJimmy.Vetayases@oracle.com intr_type, vectp->v_share, ioapic_iline);
44912683SJimmy.Vetayases@oracle.com if (!vectp->v_share)
45012683SJimmy.Vetayases@oracle.com mdb_printf("poke_cpu");
45112683SJimmy.Vetayases@oracle.com else
45212683SJimmy.Vetayases@oracle.com mdb_printf("%a", avp->av_vector);
45312683SJimmy.Vetayases@oracle.com
45412683SJimmy.Vetayases@oracle.com mdb_printf("\n");
45512683SJimmy.Vetayases@oracle.com }
456