112683SJimmy.Vetayases@oracle.com /*
212683SJimmy.Vetayases@oracle.com * CDDL HEADER START
312683SJimmy.Vetayases@oracle.com *
412683SJimmy.Vetayases@oracle.com * The contents of this file are subject to the terms of the
512683SJimmy.Vetayases@oracle.com * Common Development and Distribution License (the "License").
612683SJimmy.Vetayases@oracle.com * You may not use this file except in compliance with the License.
712683SJimmy.Vetayases@oracle.com *
812683SJimmy.Vetayases@oracle.com * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
912683SJimmy.Vetayases@oracle.com * or http://www.opensolaris.org/os/licensing.
1012683SJimmy.Vetayases@oracle.com * See the License for the specific language governing permissions
1112683SJimmy.Vetayases@oracle.com * and limitations under the License.
1212683SJimmy.Vetayases@oracle.com *
1312683SJimmy.Vetayases@oracle.com * When distributing Covered Code, include this CDDL HEADER in each
1412683SJimmy.Vetayases@oracle.com * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1512683SJimmy.Vetayases@oracle.com * If applicable, add the following below this CDDL HEADER, with the
1612683SJimmy.Vetayases@oracle.com * fields enclosed by brackets "[]" replaced with your own identifying
1712683SJimmy.Vetayases@oracle.com * information: Portions Copyright [yyyy] [name of copyright owner]
1812683SJimmy.Vetayases@oracle.com *
1912683SJimmy.Vetayases@oracle.com * CDDL HEADER END
2012683SJimmy.Vetayases@oracle.com */
2112683SJimmy.Vetayases@oracle.com /*
2212683SJimmy.Vetayases@oracle.com * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2312683SJimmy.Vetayases@oracle.com */
2412683SJimmy.Vetayases@oracle.com
2512683SJimmy.Vetayases@oracle.com #include "intr_common.h"
2612683SJimmy.Vetayases@oracle.com
2712683SJimmy.Vetayases@oracle.com /*
2812683SJimmy.Vetayases@oracle.com * Globals
2912683SJimmy.Vetayases@oracle.com */
3012683SJimmy.Vetayases@oracle.com static apic_irq_t *irq_tbl[APIC_MAX_VECTOR+1];
3112683SJimmy.Vetayases@oracle.com static char level_tbl[APIC_MAX_VECTOR+1];
3212683SJimmy.Vetayases@oracle.com static apix_impl_t *d_apixs[NCPU];
3312683SJimmy.Vetayases@oracle.com static int d_ncpus = NCPU;
3412683SJimmy.Vetayases@oracle.com
3512683SJimmy.Vetayases@oracle.com
3612683SJimmy.Vetayases@oracle.com /*
3712683SJimmy.Vetayases@oracle.com * Dump interrupt information for apix PSM.
3812683SJimmy.Vetayases@oracle.com */
3912683SJimmy.Vetayases@oracle.com /* ARGSUSED */
4012683SJimmy.Vetayases@oracle.com int
interrupt_dump_apix(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4112683SJimmy.Vetayases@oracle.com interrupt_dump_apix(uintptr_t addr, uint_t flags, int argc,
4212683SJimmy.Vetayases@oracle.com const mdb_arg_t *argv)
4312683SJimmy.Vetayases@oracle.com {
4412683SJimmy.Vetayases@oracle.com int i, j;
4512683SJimmy.Vetayases@oracle.com apix_impl_t apix;
4612683SJimmy.Vetayases@oracle.com apix_vector_t apix_vector;
4712683SJimmy.Vetayases@oracle.com struct autovec av;
4812683SJimmy.Vetayases@oracle.com apic_irq_t apic_irq;
4912683SJimmy.Vetayases@oracle.com
5012683SJimmy.Vetayases@oracle.com option_flags = 0;
5112683SJimmy.Vetayases@oracle.com if (mdb_getopts(argc, argv,
5212683SJimmy.Vetayases@oracle.com 'd', MDB_OPT_SETBITS, INTR_DISPLAY_DRVR_INST, &option_flags,
5312683SJimmy.Vetayases@oracle.com 'i', MDB_OPT_SETBITS, INTR_DISPLAY_INTRSTAT, &option_flags,
5412683SJimmy.Vetayases@oracle.com NULL) != argc)
5512683SJimmy.Vetayases@oracle.com return (DCMD_USAGE);
5612683SJimmy.Vetayases@oracle.com
5712683SJimmy.Vetayases@oracle.com if (mdb_readvar(&d_apixs, "apixs") == -1) {
5812683SJimmy.Vetayases@oracle.com mdb_warn("failed to read apixs");
5912683SJimmy.Vetayases@oracle.com return (DCMD_ERR);
6012683SJimmy.Vetayases@oracle.com }
6112683SJimmy.Vetayases@oracle.com
6212683SJimmy.Vetayases@oracle.com if (mdb_readvar(&d_ncpus, "apic_nproc") == -1) {
6312683SJimmy.Vetayases@oracle.com mdb_warn("failed to read apic_nproc");
6412683SJimmy.Vetayases@oracle.com d_ncpus = NCPU;
6512683SJimmy.Vetayases@oracle.com }
6612683SJimmy.Vetayases@oracle.com if (d_ncpus == 0 || d_ncpus > NCPU)
6712683SJimmy.Vetayases@oracle.com d_ncpus = NCPU;
6812683SJimmy.Vetayases@oracle.com
6912683SJimmy.Vetayases@oracle.com if (mdb_readvar(&irq_tbl, "apic_irq_table") == -1) {
7012683SJimmy.Vetayases@oracle.com mdb_warn("failed to read apic_irq_table");
7112683SJimmy.Vetayases@oracle.com return (DCMD_ERR);
7212683SJimmy.Vetayases@oracle.com }
7312683SJimmy.Vetayases@oracle.com
7412683SJimmy.Vetayases@oracle.com if (mdb_readvar(&level_tbl, "apic_level_intr") == -1) {
7512683SJimmy.Vetayases@oracle.com mdb_warn("failed to read apic_level_intr");
7612683SJimmy.Vetayases@oracle.com return (DCMD_ERR);
7712683SJimmy.Vetayases@oracle.com }
7812683SJimmy.Vetayases@oracle.com
7912683SJimmy.Vetayases@oracle.com /* Print the header first */
8012683SJimmy.Vetayases@oracle.com if (option_flags & INTR_DISPLAY_INTRSTAT)
8112683SJimmy.Vetayases@oracle.com mdb_printf("%<u>CPU ");
8212683SJimmy.Vetayases@oracle.com else
8312683SJimmy.Vetayases@oracle.com mdb_printf("%<u>CPU/Vect IRQ IPL Bus Trg Type "
8412683SJimmy.Vetayases@oracle.com "Share APIC/INT# ");
8512683SJimmy.Vetayases@oracle.com mdb_printf("%s %</u>\n", option_flags & INTR_DISPLAY_DRVR_INST ?
8612683SJimmy.Vetayases@oracle.com "Driver Name(s)" : "ISR");
8712683SJimmy.Vetayases@oracle.com
8812683SJimmy.Vetayases@oracle.com /* Walk all the entries */
8912683SJimmy.Vetayases@oracle.com for (i = 0; i < d_ncpus; i++) {
9012683SJimmy.Vetayases@oracle.com /* Read the per CPU apix entry */
9112683SJimmy.Vetayases@oracle.com if (mdb_vread(&apix, sizeof (apix_impl_t),
9212683SJimmy.Vetayases@oracle.com (uintptr_t)d_apixs[i]) == -1)
9312683SJimmy.Vetayases@oracle.com continue;
9412683SJimmy.Vetayases@oracle.com for (j = 0; j < APIX_NVECTOR; j++) {
9512683SJimmy.Vetayases@oracle.com /* Read the vector entry */
9612683SJimmy.Vetayases@oracle.com if (mdb_vread(&apix_vector, sizeof (apix_vector_t),
9712683SJimmy.Vetayases@oracle.com (uintptr_t)apix.x_vectbl[j]) == -1)
9812683SJimmy.Vetayases@oracle.com continue;
9912683SJimmy.Vetayases@oracle.com /* If invalid vector state; continue */
10012683SJimmy.Vetayases@oracle.com if (apix_vector.v_state == APIX_STATE_FREED ||
10112683SJimmy.Vetayases@oracle.com apix_vector.v_state == APIX_STATE_OBSOLETED)
10212683SJimmy.Vetayases@oracle.com continue;
10312683SJimmy.Vetayases@oracle.com if (apix_vector.v_type == APIX_TYPE_IPI)
10412683SJimmy.Vetayases@oracle.com continue;
10512683SJimmy.Vetayases@oracle.com if (mdb_vread(&av, sizeof (struct autovec),
10612683SJimmy.Vetayases@oracle.com (uintptr_t)(apix_vector.v_autovect)) == -1)
10712683SJimmy.Vetayases@oracle.com continue;
10812683SJimmy.Vetayases@oracle.com if ((apix_vector.v_type == APIX_TYPE_FIXED) &&
10912683SJimmy.Vetayases@oracle.com (mdb_vread(&apic_irq, sizeof (apic_irq_t),
11012683SJimmy.Vetayases@oracle.com (uintptr_t)irq_tbl[apix_vector.v_inum]) == -1))
11112683SJimmy.Vetayases@oracle.com continue;
11212683SJimmy.Vetayases@oracle.com
11312683SJimmy.Vetayases@oracle.com apix_interrupt_dump(&apix_vector, &apic_irq, &av,
11412683SJimmy.Vetayases@oracle.com NULL, level_tbl[apix_vector.v_inum]);
11512683SJimmy.Vetayases@oracle.com }
11612683SJimmy.Vetayases@oracle.com }
11712683SJimmy.Vetayases@oracle.com /* print IPIs */
11812683SJimmy.Vetayases@oracle.com if (mdb_vread(&apix, sizeof (apix_impl_t),
11912683SJimmy.Vetayases@oracle.com (uintptr_t)d_apixs[0]) != -1) {
12012683SJimmy.Vetayases@oracle.com for (j = 0; j < APIX_NVECTOR; j++) {
12112683SJimmy.Vetayases@oracle.com /* Read the vector entry */
12212683SJimmy.Vetayases@oracle.com if (mdb_vread(&apix_vector, sizeof (apix_vector_t),
12312683SJimmy.Vetayases@oracle.com (uintptr_t)apix.x_vectbl[j]) == -1)
12412683SJimmy.Vetayases@oracle.com continue;
12512683SJimmy.Vetayases@oracle.com /* If invalid vector state; continue */
12612683SJimmy.Vetayases@oracle.com if (apix_vector.v_state == APIX_STATE_FREED ||
12712683SJimmy.Vetayases@oracle.com apix_vector.v_state == APIX_STATE_OBSOLETED)
12812683SJimmy.Vetayases@oracle.com continue;
12912683SJimmy.Vetayases@oracle.com if (apix_vector.v_type != APIX_TYPE_IPI)
13012683SJimmy.Vetayases@oracle.com continue;
13112683SJimmy.Vetayases@oracle.com if (mdb_vread(&av, sizeof (struct autovec),
13212683SJimmy.Vetayases@oracle.com (uintptr_t)(apix_vector.v_autovect)) == -1) {
13312683SJimmy.Vetayases@oracle.com /* v_share for poke_cpu is 0 */
13412683SJimmy.Vetayases@oracle.com if (apix_vector.v_share != 0)
13512683SJimmy.Vetayases@oracle.com continue;
13612683SJimmy.Vetayases@oracle.com }
13712683SJimmy.Vetayases@oracle.com apix_interrupt_ipi_dump(&apix_vector, &av, NULL);
13812683SJimmy.Vetayases@oracle.com }
13912683SJimmy.Vetayases@oracle.com }
14012683SJimmy.Vetayases@oracle.com
14112683SJimmy.Vetayases@oracle.com return (DCMD_OK);
14212683SJimmy.Vetayases@oracle.com }
14312683SJimmy.Vetayases@oracle.com
14412683SJimmy.Vetayases@oracle.com /*
14512683SJimmy.Vetayases@oracle.com * MDB module linkage information:
14612683SJimmy.Vetayases@oracle.com *
14712683SJimmy.Vetayases@oracle.com * We declare a list of structures describing our dcmds, and a function
14812683SJimmy.Vetayases@oracle.com * named _mdb_init to return a pointer to our module information.
14912683SJimmy.Vetayases@oracle.com */
15012683SJimmy.Vetayases@oracle.com static const mdb_dcmd_t dcmds[] = {
15112683SJimmy.Vetayases@oracle.com { "interrupts", "?[-di]", "print interrupts", interrupt_dump_apix,
15212683SJimmy.Vetayases@oracle.com interrupt_help},
15312683SJimmy.Vetayases@oracle.com { "softint", "?[-d]", "print soft interrupts", soft_interrupt_dump,
15412683SJimmy.Vetayases@oracle.com soft_interrupt_help},
155*12825SJimmy.Vetayases@oracle.com #ifdef _KMDB
15612683SJimmy.Vetayases@oracle.com { "apic", NULL, "print apic register contents", apic },
15712683SJimmy.Vetayases@oracle.com { "ioapic", NULL, "print ioapic register contents", ioapic },
158*12825SJimmy.Vetayases@oracle.com #endif /* _KMDB */
15912683SJimmy.Vetayases@oracle.com { NULL }
16012683SJimmy.Vetayases@oracle.com };
16112683SJimmy.Vetayases@oracle.com
16212683SJimmy.Vetayases@oracle.com static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, NULL };
16312683SJimmy.Vetayases@oracle.com
16412683SJimmy.Vetayases@oracle.com const mdb_modinfo_t *
_mdb_init(void)16512683SJimmy.Vetayases@oracle.com _mdb_init(void)
16612683SJimmy.Vetayases@oracle.com {
16712683SJimmy.Vetayases@oracle.com GElf_Sym sym;
16812683SJimmy.Vetayases@oracle.com
16912683SJimmy.Vetayases@oracle.com if (mdb_lookup_by_name("gld_intr", &sym) != -1)
17012683SJimmy.Vetayases@oracle.com if (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
17112683SJimmy.Vetayases@oracle.com gld_intr_addr = (uintptr_t)sym.st_value;
17212683SJimmy.Vetayases@oracle.com
17312683SJimmy.Vetayases@oracle.com return (&modinfo);
17412683SJimmy.Vetayases@oracle.com }
175