xref: /onnv-gate/usr/src/cmd/mdb/i86pc/modules/apix/apix.c (revision 12825:e35468461453)
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