xref: /titanic_52/usr/src/cmd/mdb/i86pc/modules/apix/apix.c (revision 5cd376e8b7030707d78315f63adb4bb2b4d9963e)
17ff178cdSJimmy Vetayases /*
27ff178cdSJimmy Vetayases  * CDDL HEADER START
37ff178cdSJimmy Vetayases  *
47ff178cdSJimmy Vetayases  * The contents of this file are subject to the terms of the
57ff178cdSJimmy Vetayases  * Common Development and Distribution License (the "License").
67ff178cdSJimmy Vetayases  * You may not use this file except in compliance with the License.
77ff178cdSJimmy Vetayases  *
87ff178cdSJimmy Vetayases  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97ff178cdSJimmy Vetayases  * or http://www.opensolaris.org/os/licensing.
107ff178cdSJimmy Vetayases  * See the License for the specific language governing permissions
117ff178cdSJimmy Vetayases  * and limitations under the License.
127ff178cdSJimmy Vetayases  *
137ff178cdSJimmy Vetayases  * When distributing Covered Code, include this CDDL HEADER in each
147ff178cdSJimmy Vetayases  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157ff178cdSJimmy Vetayases  * If applicable, add the following below this CDDL HEADER, with the
167ff178cdSJimmy Vetayases  * fields enclosed by brackets "[]" replaced with your own identifying
177ff178cdSJimmy Vetayases  * information: Portions Copyright [yyyy] [name of copyright owner]
187ff178cdSJimmy Vetayases  *
197ff178cdSJimmy Vetayases  * CDDL HEADER END
207ff178cdSJimmy Vetayases  */
217ff178cdSJimmy Vetayases /*
227ff178cdSJimmy Vetayases  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
237ff178cdSJimmy Vetayases  */
247ff178cdSJimmy Vetayases 
257ff178cdSJimmy Vetayases #include "intr_common.h"
267ff178cdSJimmy Vetayases 
277ff178cdSJimmy Vetayases /*
287ff178cdSJimmy Vetayases  * Globals
297ff178cdSJimmy Vetayases  */
307ff178cdSJimmy Vetayases static apic_irq_t	*irq_tbl[APIC_MAX_VECTOR+1];
317ff178cdSJimmy Vetayases static char		level_tbl[APIC_MAX_VECTOR+1];
327ff178cdSJimmy Vetayases static apix_impl_t *d_apixs[NCPU];
337ff178cdSJimmy Vetayases static int d_ncpus = NCPU;
347ff178cdSJimmy Vetayases 
357ff178cdSJimmy Vetayases 
367ff178cdSJimmy Vetayases /*
377ff178cdSJimmy Vetayases  * Dump interrupt information for apix PSM.
387ff178cdSJimmy Vetayases  */
397ff178cdSJimmy Vetayases /* ARGSUSED */
407ff178cdSJimmy Vetayases int
417ff178cdSJimmy Vetayases interrupt_dump_apix(uintptr_t addr, uint_t flags, int argc,
427ff178cdSJimmy Vetayases     const mdb_arg_t *argv)
437ff178cdSJimmy Vetayases {
447ff178cdSJimmy Vetayases 	int i, j;
457ff178cdSJimmy Vetayases 	apix_impl_t apix;
467ff178cdSJimmy Vetayases 	apix_vector_t apix_vector;
477ff178cdSJimmy Vetayases 	struct autovec av;
487ff178cdSJimmy Vetayases 	apic_irq_t apic_irq;
497ff178cdSJimmy Vetayases 
507ff178cdSJimmy Vetayases 	option_flags = 0;
517ff178cdSJimmy Vetayases 	if (mdb_getopts(argc, argv,
527ff178cdSJimmy Vetayases 	    'd', MDB_OPT_SETBITS, INTR_DISPLAY_DRVR_INST, &option_flags,
537ff178cdSJimmy Vetayases 	    'i', MDB_OPT_SETBITS, INTR_DISPLAY_INTRSTAT, &option_flags,
547ff178cdSJimmy Vetayases 	    NULL) != argc)
557ff178cdSJimmy Vetayases 		return (DCMD_USAGE);
567ff178cdSJimmy Vetayases 
577ff178cdSJimmy Vetayases 	if (mdb_readvar(&d_apixs, "apixs") == -1) {
587ff178cdSJimmy Vetayases 		mdb_warn("failed to read apixs");
597ff178cdSJimmy Vetayases 		return (DCMD_ERR);
607ff178cdSJimmy Vetayases 	}
617ff178cdSJimmy Vetayases 
627ff178cdSJimmy Vetayases 	if (mdb_readvar(&d_ncpus, "apic_nproc") == -1) {
637ff178cdSJimmy Vetayases 		mdb_warn("failed to read apic_nproc");
647ff178cdSJimmy Vetayases 		d_ncpus = NCPU;
657ff178cdSJimmy Vetayases 	}
667ff178cdSJimmy Vetayases 	if (d_ncpus == 0 || d_ncpus > NCPU)
677ff178cdSJimmy Vetayases 		d_ncpus = NCPU;
687ff178cdSJimmy Vetayases 
697ff178cdSJimmy Vetayases 	if (mdb_readvar(&irq_tbl, "apic_irq_table") == -1) {
707ff178cdSJimmy Vetayases 		mdb_warn("failed to read apic_irq_table");
717ff178cdSJimmy Vetayases 		return (DCMD_ERR);
727ff178cdSJimmy Vetayases 	}
737ff178cdSJimmy Vetayases 
747ff178cdSJimmy Vetayases 	if (mdb_readvar(&level_tbl, "apic_level_intr") == -1) {
757ff178cdSJimmy Vetayases 		mdb_warn("failed to read apic_level_intr");
767ff178cdSJimmy Vetayases 		return (DCMD_ERR);
777ff178cdSJimmy Vetayases 	}
787ff178cdSJimmy Vetayases 
797ff178cdSJimmy Vetayases 	/* Print the header first */
807ff178cdSJimmy Vetayases 	if (option_flags & INTR_DISPLAY_INTRSTAT)
817ff178cdSJimmy Vetayases 		mdb_printf("%<u>CPU ");
827ff178cdSJimmy Vetayases 	else
837ff178cdSJimmy Vetayases 		mdb_printf("%<u>CPU/Vect  IRQ IPL Bus    Trg Type   "
847ff178cdSJimmy Vetayases 		    "Share APIC/INT# ");
857ff178cdSJimmy Vetayases 	mdb_printf("%s %</u>\n", option_flags & INTR_DISPLAY_DRVR_INST ?
867ff178cdSJimmy Vetayases 	    "Driver Name(s)" : "ISR");
877ff178cdSJimmy Vetayases 
887ff178cdSJimmy Vetayases 	/* Walk all the entries */
897ff178cdSJimmy Vetayases 	for (i = 0; i < d_ncpus; i++) {
907ff178cdSJimmy Vetayases 		/* Read the per CPU apix entry */
917ff178cdSJimmy Vetayases 		if (mdb_vread(&apix, sizeof (apix_impl_t),
927ff178cdSJimmy Vetayases 		    (uintptr_t)d_apixs[i]) == -1)
937ff178cdSJimmy Vetayases 			continue;
947ff178cdSJimmy Vetayases 		for (j = 0; j < APIX_NVECTOR; j++) {
957ff178cdSJimmy Vetayases 			/* Read the vector entry */
967ff178cdSJimmy Vetayases 			if (mdb_vread(&apix_vector, sizeof (apix_vector_t),
977ff178cdSJimmy Vetayases 			    (uintptr_t)apix.x_vectbl[j]) == -1)
987ff178cdSJimmy Vetayases 				continue;
997ff178cdSJimmy Vetayases 			/* If invalid vector state; continue */
1007ff178cdSJimmy Vetayases 			if (apix_vector.v_state == APIX_STATE_FREED ||
1017ff178cdSJimmy Vetayases 			    apix_vector.v_state == APIX_STATE_OBSOLETED)
1027ff178cdSJimmy Vetayases 				continue;
1037ff178cdSJimmy Vetayases 			if (apix_vector.v_type == APIX_TYPE_IPI)
1047ff178cdSJimmy Vetayases 				continue;
1057ff178cdSJimmy Vetayases 			if (mdb_vread(&av, sizeof (struct autovec),
1067ff178cdSJimmy Vetayases 			    (uintptr_t)(apix_vector.v_autovect)) == -1)
1077ff178cdSJimmy Vetayases 				continue;
1087ff178cdSJimmy Vetayases 			if ((apix_vector.v_type == APIX_TYPE_FIXED) &&
1097ff178cdSJimmy Vetayases 			    (mdb_vread(&apic_irq, sizeof (apic_irq_t),
1107ff178cdSJimmy Vetayases 			    (uintptr_t)irq_tbl[apix_vector.v_inum]) == -1))
1117ff178cdSJimmy Vetayases 				continue;
1127ff178cdSJimmy Vetayases 
1137ff178cdSJimmy Vetayases 			apix_interrupt_dump(&apix_vector, &apic_irq, &av,
1147ff178cdSJimmy Vetayases 			    NULL, level_tbl[apix_vector.v_inum]);
1157ff178cdSJimmy Vetayases 		}
1167ff178cdSJimmy Vetayases 	}
1177ff178cdSJimmy Vetayases 	/* print IPIs */
1187ff178cdSJimmy Vetayases 	if (mdb_vread(&apix, sizeof (apix_impl_t),
1197ff178cdSJimmy Vetayases 	    (uintptr_t)d_apixs[0]) != -1) {
1207ff178cdSJimmy Vetayases 		for (j = 0; j < APIX_NVECTOR; j++) {
1217ff178cdSJimmy Vetayases 			/* Read the vector entry */
1227ff178cdSJimmy Vetayases 			if (mdb_vread(&apix_vector, sizeof (apix_vector_t),
1237ff178cdSJimmy Vetayases 			    (uintptr_t)apix.x_vectbl[j]) == -1)
1247ff178cdSJimmy Vetayases 				continue;
1257ff178cdSJimmy Vetayases 			/* If invalid vector state; continue */
1267ff178cdSJimmy Vetayases 			if (apix_vector.v_state == APIX_STATE_FREED ||
1277ff178cdSJimmy Vetayases 			    apix_vector.v_state == APIX_STATE_OBSOLETED)
1287ff178cdSJimmy Vetayases 				continue;
1297ff178cdSJimmy Vetayases 			if (apix_vector.v_type != APIX_TYPE_IPI)
1307ff178cdSJimmy Vetayases 				continue;
1317ff178cdSJimmy Vetayases 			if (mdb_vread(&av, sizeof (struct autovec),
1327ff178cdSJimmy Vetayases 			    (uintptr_t)(apix_vector.v_autovect)) == -1) {
1337ff178cdSJimmy Vetayases 				/* v_share for poke_cpu is 0 */
1347ff178cdSJimmy Vetayases 				if (apix_vector.v_share != 0)
1357ff178cdSJimmy Vetayases 					continue;
1367ff178cdSJimmy Vetayases 			}
1377ff178cdSJimmy Vetayases 			apix_interrupt_ipi_dump(&apix_vector, &av, NULL);
1387ff178cdSJimmy Vetayases 		}
1397ff178cdSJimmy Vetayases 	}
1407ff178cdSJimmy Vetayases 
1417ff178cdSJimmy Vetayases 	return (DCMD_OK);
1427ff178cdSJimmy Vetayases }
1437ff178cdSJimmy Vetayases 
1447ff178cdSJimmy Vetayases /*
1457ff178cdSJimmy Vetayases  * MDB module linkage information:
1467ff178cdSJimmy Vetayases  *
1477ff178cdSJimmy Vetayases  * We declare a list of structures describing our dcmds, and a function
1487ff178cdSJimmy Vetayases  * named _mdb_init to return a pointer to our module information.
1497ff178cdSJimmy Vetayases  */
1507ff178cdSJimmy Vetayases static const mdb_dcmd_t dcmds[] = {
1517ff178cdSJimmy Vetayases 	{ "interrupts", "?[-di]", "print interrupts", interrupt_dump_apix,
1527ff178cdSJimmy Vetayases 	    interrupt_help},
1537ff178cdSJimmy Vetayases 	{ "softint", "?[-d]", "print soft interrupts", soft_interrupt_dump,
1547ff178cdSJimmy Vetayases 	    soft_interrupt_help},
155*5cd376e8SJimmy Vetayases #ifdef _KMDB
1567ff178cdSJimmy Vetayases 	{ "apic", NULL, "print apic register contents", apic },
1577ff178cdSJimmy Vetayases 	{ "ioapic", NULL, "print ioapic register contents", ioapic },
158*5cd376e8SJimmy Vetayases #endif /* _KMDB */
1597ff178cdSJimmy Vetayases 	{ NULL }
1607ff178cdSJimmy Vetayases };
1617ff178cdSJimmy Vetayases 
1627ff178cdSJimmy Vetayases static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, NULL };
1637ff178cdSJimmy Vetayases 
1647ff178cdSJimmy Vetayases const mdb_modinfo_t *
1657ff178cdSJimmy Vetayases _mdb_init(void)
1667ff178cdSJimmy Vetayases {
1677ff178cdSJimmy Vetayases 	GElf_Sym	sym;
1687ff178cdSJimmy Vetayases 
1697ff178cdSJimmy Vetayases 	if (mdb_lookup_by_name("gld_intr", &sym) != -1)
1707ff178cdSJimmy Vetayases 		if (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
1717ff178cdSJimmy Vetayases 			gld_intr_addr = (uintptr_t)sym.st_value;
1727ff178cdSJimmy Vetayases 
1737ff178cdSJimmy Vetayases 	return (&modinfo);
1747ff178cdSJimmy Vetayases }
175