4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include "intr_common.h"
27 static struct av_head avec_tbl
[APIC_MAX_VECTOR
+1];
28 static uint16_t shared_tbl
[MAX_ISA_IRQ
+ 1];
31 interrupt_print_bus(uintptr_t dip_addr
)
33 char bind_name
[MAXPATHLEN
+ 1];
34 struct dev_info dev_info
;
36 if (mdb_vread(&dev_info
, sizeof (dev_info
), dip_addr
) == -1) {
37 mdb_warn("failed to read child dip");
41 while (dev_info
.devi_parent
!= 0) {
42 if (mdb_vread(&dev_info
, sizeof (dev_info
),
43 (uintptr_t)dev_info
.devi_parent
) == -1)
46 (void) mdb_readstr(bind_name
, sizeof (bind_name
),
47 (uintptr_t)dev_info
.devi_binding_name
);
48 if (strcmp(bind_name
, "isa") == 0)
50 else if (strcmp(bind_name
, "pci") == 0 ||
51 strcmp(bind_name
, "npe") == 0)
59 * uppc_interrupt_dump:
60 * Dump uppc(7d) interrupt information.
64 uppc_interrupt_dump(uintptr_t addr
, uint_t flags
, int argc
,
65 const mdb_arg_t
*argv
)
68 boolean_t found
= B_FALSE
;
72 if (mdb_getopts(argc
, argv
,
73 'd', MDB_OPT_SETBITS
, INTR_DISPLAY_DRVR_INST
, &option_flags
,
74 'i', MDB_OPT_SETBITS
, INTR_DISPLAY_INTRSTAT
, &option_flags
,
78 if (mdb_readvar(&avec_tbl
, "autovect") == -1) {
79 mdb_warn("failed to read autovect");
83 if (mdb_readvar(&shared_tbl
, "uppc_irq_shared_table") == -1) {
84 mdb_warn("failed to read uppc_irq_shared_table");
89 * By default, on all x86 systems ::interrupts from uppc gets
90 * loaded first. For APIC systems the ::interrupts from either
91 * apix or pcplusmp ought to be executed. Confusion stems as
92 * these three modules export the same dcmd.
94 for (i
= 0; i
< MAX_ISA_IRQ
+ 1; i
++)
100 if (found
== B_FALSE
) {
101 if (mdb_lookup_by_obj("apix", "apixs", NULL
) == 0) {
102 return (mdb_call_dcmd("apix`interrupts",
103 addr
, flags
, argc
, argv
));
104 } else if (mdb_lookup_by_obj("pcplusmp", "apic_irq_table",
106 return (mdb_call_dcmd("pcplusmp`interrupts",
107 addr
, flags
, argc
, argv
));
111 /* Print the header first */
112 if (option_flags
& INTR_DISPLAY_INTRSTAT
)
113 mdb_printf("%<u>CPU ");
115 mdb_printf("%<u>IRQ Vector IPL(lo/hi) Bus Share ");
116 mdb_printf("%s %</u>\n", option_flags
& INTR_DISPLAY_DRVR_INST
?
117 "Driver Name(s)" : "ISR(s)");
119 /* Walk all the entries */
120 for (i
= 0; i
< MAX_ISA_IRQ
+ 1; i
++) {
121 /* Read the entry, if invalid continue */
122 if (mdb_vread(&avhp
, sizeof (struct autovec
),
123 (uintptr_t)avec_tbl
[i
].avh_link
) == -1)
126 /* Print each interrupt entry */
127 if (option_flags
& INTR_DISPLAY_INTRSTAT
)
128 mdb_printf("cpu0\t");
130 mdb_printf("%-3d 0x%2x %4d/%-2d %-4s %-3d ",
131 i
, i
+ PIC_VECTBASE
, avec_tbl
[i
].avh_lo_pri
,
132 avec_tbl
[i
].avh_hi_pri
, avhp
.av_dip
?
133 interrupt_print_bus((uintptr_t)avhp
.av_dip
) : " - ",
137 interrupt_print_isr((uintptr_t)avhp
.av_vector
,
138 (uintptr_t)avhp
.av_intarg1
, (uintptr_t)avhp
.av_dip
);
140 for (j
= 1; j
< shared_tbl
[i
]; j
++) {
141 if (mdb_vread(&avhp
, sizeof (struct autovec
),
142 (uintptr_t)avhp
.av_link
) != -1) {
144 interrupt_print_isr((uintptr_t)avhp
.av_vector
,
145 (uintptr_t)avhp
.av_intarg1
,
146 (uintptr_t)avhp
.av_dip
);
159 * MDB module linkage information:
161 static const mdb_dcmd_t dcmds
[] = {
162 { "interrupts", "?[-di]", "print interrupts", uppc_interrupt_dump
,
164 { "softint", "?[-d]", "print soft interrupts", soft_interrupt_dump
,
165 soft_interrupt_help
},
169 static const mdb_modinfo_t modinfo
= { MDB_API_VERSION
, dcmds
, NULL
};
171 const mdb_modinfo_t
*
176 if (mdb_lookup_by_name("gld_intr", &sym
) != -1)
177 if (GELF_ST_TYPE(sym
.st_info
) == STT_FUNC
)
178 gld_intr_addr
= (uintptr_t)sym
.st_value
;