xref: /titanic_50/usr/src/cmd/mdb/i86pc/modules/apix/apix.c (revision 6a634c9dca3093f3922e4b7ab826d7bdf17bf78e)
1*7ff178cdSJimmy Vetayases /*
2*7ff178cdSJimmy Vetayases  * CDDL HEADER START
3*7ff178cdSJimmy Vetayases  *
4*7ff178cdSJimmy Vetayases  * The contents of this file are subject to the terms of the
5*7ff178cdSJimmy Vetayases  * Common Development and Distribution License (the "License").
6*7ff178cdSJimmy Vetayases  * You may not use this file except in compliance with the License.
7*7ff178cdSJimmy Vetayases  *
8*7ff178cdSJimmy Vetayases  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7ff178cdSJimmy Vetayases  * or http://www.opensolaris.org/os/licensing.
10*7ff178cdSJimmy Vetayases  * See the License for the specific language governing permissions
11*7ff178cdSJimmy Vetayases  * and limitations under the License.
12*7ff178cdSJimmy Vetayases  *
13*7ff178cdSJimmy Vetayases  * When distributing Covered Code, include this CDDL HEADER in each
14*7ff178cdSJimmy Vetayases  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7ff178cdSJimmy Vetayases  * If applicable, add the following below this CDDL HEADER, with the
16*7ff178cdSJimmy Vetayases  * fields enclosed by brackets "[]" replaced with your own identifying
17*7ff178cdSJimmy Vetayases  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7ff178cdSJimmy Vetayases  *
19*7ff178cdSJimmy Vetayases  * CDDL HEADER END
20*7ff178cdSJimmy Vetayases  */
21*7ff178cdSJimmy Vetayases /*
22*7ff178cdSJimmy Vetayases  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23*7ff178cdSJimmy Vetayases  */
24*7ff178cdSJimmy Vetayases 
25*7ff178cdSJimmy Vetayases #include "intr_common.h"
26*7ff178cdSJimmy Vetayases 
27*7ff178cdSJimmy Vetayases /*
28*7ff178cdSJimmy Vetayases  * Globals
29*7ff178cdSJimmy Vetayases  */
30*7ff178cdSJimmy Vetayases static apic_irq_t	*irq_tbl[APIC_MAX_VECTOR+1];
31*7ff178cdSJimmy Vetayases static char		level_tbl[APIC_MAX_VECTOR+1];
32*7ff178cdSJimmy Vetayases static apix_impl_t *d_apixs[NCPU];
33*7ff178cdSJimmy Vetayases static int d_ncpus = NCPU;
34*7ff178cdSJimmy Vetayases 
35*7ff178cdSJimmy Vetayases 
36*7ff178cdSJimmy Vetayases /*
37*7ff178cdSJimmy Vetayases  * Dump interrupt information for apix PSM.
38*7ff178cdSJimmy Vetayases  */
39*7ff178cdSJimmy Vetayases /* ARGSUSED */
40*7ff178cdSJimmy Vetayases int
interrupt_dump_apix(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)41*7ff178cdSJimmy Vetayases interrupt_dump_apix(uintptr_t addr, uint_t flags, int argc,
42*7ff178cdSJimmy Vetayases     const mdb_arg_t *argv)
43*7ff178cdSJimmy Vetayases {
44*7ff178cdSJimmy Vetayases 	int i, j;
45*7ff178cdSJimmy Vetayases 	apix_impl_t apix;
46*7ff178cdSJimmy Vetayases 	apix_vector_t apix_vector;
47*7ff178cdSJimmy Vetayases 	struct autovec av;
48*7ff178cdSJimmy Vetayases 	apic_irq_t apic_irq;
49*7ff178cdSJimmy Vetayases 
50*7ff178cdSJimmy Vetayases 	option_flags = 0;
51*7ff178cdSJimmy Vetayases 	if (mdb_getopts(argc, argv,
52*7ff178cdSJimmy Vetayases 	    'd', MDB_OPT_SETBITS, INTR_DISPLAY_DRVR_INST, &option_flags,
53*7ff178cdSJimmy Vetayases 	    'i', MDB_OPT_SETBITS, INTR_DISPLAY_INTRSTAT, &option_flags,
54*7ff178cdSJimmy Vetayases 	    NULL) != argc)
55*7ff178cdSJimmy Vetayases 		return (DCMD_USAGE);
56*7ff178cdSJimmy Vetayases 
57*7ff178cdSJimmy Vetayases 	if (mdb_readvar(&d_apixs, "apixs") == -1) {
58*7ff178cdSJimmy Vetayases 		mdb_warn("failed to read apixs");
59*7ff178cdSJimmy Vetayases 		return (DCMD_ERR);
60*7ff178cdSJimmy Vetayases 	}
61*7ff178cdSJimmy Vetayases 
62*7ff178cdSJimmy Vetayases 	if (mdb_readvar(&d_ncpus, "apic_nproc") == -1) {
63*7ff178cdSJimmy Vetayases 		mdb_warn("failed to read apic_nproc");
64*7ff178cdSJimmy Vetayases 		d_ncpus = NCPU;
65*7ff178cdSJimmy Vetayases 	}
66*7ff178cdSJimmy Vetayases 	if (d_ncpus == 0 || d_ncpus > NCPU)
67*7ff178cdSJimmy Vetayases 		d_ncpus = NCPU;
68*7ff178cdSJimmy Vetayases 
69*7ff178cdSJimmy Vetayases 	if (mdb_readvar(&irq_tbl, "apic_irq_table") == -1) {
70*7ff178cdSJimmy Vetayases 		mdb_warn("failed to read apic_irq_table");
71*7ff178cdSJimmy Vetayases 		return (DCMD_ERR);
72*7ff178cdSJimmy Vetayases 	}
73*7ff178cdSJimmy Vetayases 
74*7ff178cdSJimmy Vetayases 	if (mdb_readvar(&level_tbl, "apic_level_intr") == -1) {
75*7ff178cdSJimmy Vetayases 		mdb_warn("failed to read apic_level_intr");
76*7ff178cdSJimmy Vetayases 		return (DCMD_ERR);
77*7ff178cdSJimmy Vetayases 	}
78*7ff178cdSJimmy Vetayases 
79*7ff178cdSJimmy Vetayases 	/* Print the header first */
80*7ff178cdSJimmy Vetayases 	if (option_flags & INTR_DISPLAY_INTRSTAT)
81*7ff178cdSJimmy Vetayases 		mdb_printf("%<u>CPU ");
82*7ff178cdSJimmy Vetayases 	else
83*7ff178cdSJimmy Vetayases 		mdb_printf("%<u>CPU/Vect  IRQ IPL Bus    Trg Type   "
84*7ff178cdSJimmy Vetayases 		    "Share APIC/INT# ");
85*7ff178cdSJimmy Vetayases 	mdb_printf("%s %</u>\n", option_flags & INTR_DISPLAY_DRVR_INST ?
86*7ff178cdSJimmy Vetayases 	    "Driver Name(s)" : "ISR");
87*7ff178cdSJimmy Vetayases 
88*7ff178cdSJimmy Vetayases 	/* Walk all the entries */
89*7ff178cdSJimmy Vetayases 	for (i = 0; i < d_ncpus; i++) {
90*7ff178cdSJimmy Vetayases 		/* Read the per CPU apix entry */
91*7ff178cdSJimmy Vetayases 		if (mdb_vread(&apix, sizeof (apix_impl_t),
92*7ff178cdSJimmy Vetayases 		    (uintptr_t)d_apixs[i]) == -1)
93*7ff178cdSJimmy Vetayases 			continue;
94*7ff178cdSJimmy Vetayases 		for (j = 0; j < APIX_NVECTOR; j++) {
95*7ff178cdSJimmy Vetayases 			/* Read the vector entry */
96*7ff178cdSJimmy Vetayases 			if (mdb_vread(&apix_vector, sizeof (apix_vector_t),
97*7ff178cdSJimmy Vetayases 			    (uintptr_t)apix.x_vectbl[j]) == -1)
98*7ff178cdSJimmy Vetayases 				continue;
99*7ff178cdSJimmy Vetayases 			/* If invalid vector state; continue */
100*7ff178cdSJimmy Vetayases 			if (apix_vector.v_state == APIX_STATE_FREED ||
101*7ff178cdSJimmy Vetayases 			    apix_vector.v_state == APIX_STATE_OBSOLETED)
102*7ff178cdSJimmy Vetayases 				continue;
103*7ff178cdSJimmy Vetayases 			if (apix_vector.v_type == APIX_TYPE_IPI)
104*7ff178cdSJimmy Vetayases 				continue;
105*7ff178cdSJimmy Vetayases 			if (mdb_vread(&av, sizeof (struct autovec),
106*7ff178cdSJimmy Vetayases 			    (uintptr_t)(apix_vector.v_autovect)) == -1)
107*7ff178cdSJimmy Vetayases 				continue;
108*7ff178cdSJimmy Vetayases 			if ((apix_vector.v_type == APIX_TYPE_FIXED) &&
109*7ff178cdSJimmy Vetayases 			    (mdb_vread(&apic_irq, sizeof (apic_irq_t),
110*7ff178cdSJimmy Vetayases 			    (uintptr_t)irq_tbl[apix_vector.v_inum]) == -1))
111*7ff178cdSJimmy Vetayases 				continue;
112*7ff178cdSJimmy Vetayases 
113*7ff178cdSJimmy Vetayases 			apix_interrupt_dump(&apix_vector, &apic_irq, &av,
114*7ff178cdSJimmy Vetayases 			    NULL, level_tbl[apix_vector.v_inum]);
115*7ff178cdSJimmy Vetayases 		}
116*7ff178cdSJimmy Vetayases 	}
117*7ff178cdSJimmy Vetayases 	/* print IPIs */
118*7ff178cdSJimmy Vetayases 	if (mdb_vread(&apix, sizeof (apix_impl_t),
119*7ff178cdSJimmy Vetayases 	    (uintptr_t)d_apixs[0]) != -1) {
120*7ff178cdSJimmy Vetayases 		for (j = 0; j < APIX_NVECTOR; j++) {
121*7ff178cdSJimmy Vetayases 			/* Read the vector entry */
122*7ff178cdSJimmy Vetayases 			if (mdb_vread(&apix_vector, sizeof (apix_vector_t),
123*7ff178cdSJimmy Vetayases 			    (uintptr_t)apix.x_vectbl[j]) == -1)
124*7ff178cdSJimmy Vetayases 				continue;
125*7ff178cdSJimmy Vetayases 			/* If invalid vector state; continue */
126*7ff178cdSJimmy Vetayases 			if (apix_vector.v_state == APIX_STATE_FREED ||
127*7ff178cdSJimmy Vetayases 			    apix_vector.v_state == APIX_STATE_OBSOLETED)
128*7ff178cdSJimmy Vetayases 				continue;
129*7ff178cdSJimmy Vetayases 			if (apix_vector.v_type != APIX_TYPE_IPI)
130*7ff178cdSJimmy Vetayases 				continue;
131*7ff178cdSJimmy Vetayases 			if (mdb_vread(&av, sizeof (struct autovec),
132*7ff178cdSJimmy Vetayases 			    (uintptr_t)(apix_vector.v_autovect)) == -1) {
133*7ff178cdSJimmy Vetayases 				/* v_share for poke_cpu is 0 */
134*7ff178cdSJimmy Vetayases 				if (apix_vector.v_share != 0)
135*7ff178cdSJimmy Vetayases 					continue;
136*7ff178cdSJimmy Vetayases 			}
137*7ff178cdSJimmy Vetayases 			apix_interrupt_ipi_dump(&apix_vector, &av, NULL);
138*7ff178cdSJimmy Vetayases 		}
139*7ff178cdSJimmy Vetayases 	}
140*7ff178cdSJimmy Vetayases 
141*7ff178cdSJimmy Vetayases 	return (DCMD_OK);
142*7ff178cdSJimmy Vetayases }
143*7ff178cdSJimmy Vetayases 
144*7ff178cdSJimmy Vetayases /*
145*7ff178cdSJimmy Vetayases  * MDB module linkage information:
146*7ff178cdSJimmy Vetayases  *
147*7ff178cdSJimmy Vetayases  * We declare a list of structures describing our dcmds, and a function
148*7ff178cdSJimmy Vetayases  * named _mdb_init to return a pointer to our module information.
149*7ff178cdSJimmy Vetayases  */
150*7ff178cdSJimmy Vetayases static const mdb_dcmd_t dcmds[] = {
151*7ff178cdSJimmy Vetayases 	{ "interrupts", "?[-di]", "print interrupts", interrupt_dump_apix,
152*7ff178cdSJimmy Vetayases 	    interrupt_help},
153*7ff178cdSJimmy Vetayases 	{ "softint", "?[-d]", "print soft interrupts", soft_interrupt_dump,
154*7ff178cdSJimmy Vetayases 	    soft_interrupt_help},
1555cd376e8SJimmy Vetayases #ifdef _KMDB
156*7ff178cdSJimmy Vetayases 	{ "apic", NULL, "print apic register contents", apic },
157*7ff178cdSJimmy Vetayases 	{ "ioapic", NULL, "print ioapic register contents", ioapic },
1585cd376e8SJimmy Vetayases #endif /* _KMDB */
159*7ff178cdSJimmy Vetayases 	{ NULL }
160*7ff178cdSJimmy Vetayases };
161*7ff178cdSJimmy Vetayases 
162*7ff178cdSJimmy Vetayases static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, NULL };
163*7ff178cdSJimmy Vetayases 
164*7ff178cdSJimmy Vetayases const mdb_modinfo_t *
_mdb_init(void)165*7ff178cdSJimmy Vetayases _mdb_init(void)
166*7ff178cdSJimmy Vetayases {
167*7ff178cdSJimmy Vetayases 	GElf_Sym	sym;
168*7ff178cdSJimmy Vetayases 
169*7ff178cdSJimmy Vetayases 	if (mdb_lookup_by_name("gld_intr", &sym) != -1)
170*7ff178cdSJimmy Vetayases 		if (GELF_ST_TYPE(sym.st_info) == STT_FUNC)
171*7ff178cdSJimmy Vetayases 			gld_intr_addr = (uintptr_t)sym.st_value;
172*7ff178cdSJimmy Vetayases 
173*7ff178cdSJimmy Vetayases 	return (&modinfo);
174*7ff178cdSJimmy Vetayases }
175