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) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018 Joyent, Inc.
26 #include "intr_common.h"
31 static apic_irq_t
*irq_tbl
[APIC_MAX_VECTOR
+1];
32 static char level_tbl
[APIC_MAX_VECTOR
+1];
33 static apix_impl_t
*d_apixs
[NCPU
];
34 static int d_ncpus
= NCPU
;
38 * Dump interrupt information for apix PSM.
42 interrupt_dump_apix(uintptr_t addr
, uint_t flags
, int argc
,
43 const mdb_arg_t
*argv
)
47 apix_vector_t apix_vector
;
52 if (mdb_getopts(argc
, argv
,
53 'd', MDB_OPT_SETBITS
, INTR_DISPLAY_DRVR_INST
, &option_flags
,
54 'i', MDB_OPT_SETBITS
, INTR_DISPLAY_INTRSTAT
, &option_flags
,
58 if (mdb_readvar(&d_apixs
, "apixs") == -1) {
59 mdb_warn("failed to read apixs");
63 if (mdb_readvar(&d_ncpus
, "apic_nproc") == -1) {
64 mdb_warn("failed to read apic_nproc");
67 if (d_ncpus
== 0 || d_ncpus
> NCPU
)
70 if (mdb_readvar(&irq_tbl
, "apic_irq_table") == -1) {
71 mdb_warn("failed to read apic_irq_table");
75 if (mdb_readvar(&level_tbl
, "apic_level_intr") == -1) {
76 mdb_warn("failed to read apic_level_intr");
80 /* Print the header first */
81 if (option_flags
& INTR_DISPLAY_INTRSTAT
)
82 mdb_printf("%<u>CPU ");
84 mdb_printf("%<u>CPU/Vect IRQ IPL Bus Trg Type "
86 mdb_printf("%s %</u>\n", option_flags
& INTR_DISPLAY_DRVR_INST
?
87 "Driver Name(s)" : "ISR");
89 /* Walk all the entries */
90 for (i
= 0; i
< d_ncpus
; i
++) {
91 /* Read the per CPU apix entry */
92 if (mdb_vread(&apix
, sizeof (apix_impl_t
),
93 (uintptr_t)d_apixs
[i
]) == -1)
95 for (j
= 0; j
< APIX_NVECTOR
; j
++) {
96 /* Read the vector entry */
97 if (mdb_vread(&apix_vector
, sizeof (apix_vector_t
),
98 (uintptr_t)apix
.x_vectbl
[j
]) == -1)
100 /* If invalid vector state; continue */
101 if (apix_vector
.v_state
== APIX_STATE_FREED
||
102 apix_vector
.v_state
== APIX_STATE_OBSOLETED
)
104 if (apix_vector
.v_type
== APIX_TYPE_IPI
)
106 if (mdb_vread(&av
, sizeof (struct autovec
),
107 (uintptr_t)(apix_vector
.v_autovect
)) == -1)
109 if ((apix_vector
.v_type
== APIX_TYPE_FIXED
) &&
110 (mdb_vread(&apic_irq
, sizeof (apic_irq_t
),
111 (uintptr_t)irq_tbl
[apix_vector
.v_inum
]) == -1))
114 apix_interrupt_dump(&apix_vector
, &apic_irq
, &av
,
115 NULL
, level_tbl
[apix_vector
.v_inum
]);
119 if (mdb_vread(&apix
, sizeof (apix_impl_t
),
120 (uintptr_t)d_apixs
[0]) != -1) {
121 for (j
= 0; j
< APIX_NVECTOR
; j
++) {
122 /* Read the vector entry */
123 if (mdb_vread(&apix_vector
, sizeof (apix_vector_t
),
124 (uintptr_t)apix
.x_vectbl
[j
]) == -1)
126 /* If invalid vector state; continue */
127 if (apix_vector
.v_state
== APIX_STATE_FREED
||
128 apix_vector
.v_state
== APIX_STATE_OBSOLETED
)
130 if (apix_vector
.v_type
!= APIX_TYPE_IPI
)
132 if (mdb_vread(&av
, sizeof (struct autovec
),
133 (uintptr_t)(apix_vector
.v_autovect
)) == -1) {
134 /* v_share for poke_cpu is 0 */
135 if (apix_vector
.v_share
!= 0)
138 apix_interrupt_ipi_dump(&apix_vector
, &av
, NULL
);
146 * MDB module linkage information:
148 * We declare a list of structures describing our dcmds, and a function
149 * named _mdb_init to return a pointer to our module information.
151 static const mdb_dcmd_t dcmds
[] = {
152 { "interrupts", "?[-di]", "print interrupts", interrupt_dump_apix
,
154 { "softint", "?[-d]", "print soft interrupts", soft_interrupt_dump
,
155 soft_interrupt_help
},
157 { "apic", NULL
, "print apic register contents", apic
},
158 { "ioapic", NULL
, "print ioapic register contents", ioapic
},
163 static const mdb_modinfo_t modinfo
= { MDB_API_VERSION
, dcmds
, NULL
};
165 const mdb_modinfo_t
*
170 if (mdb_lookup_by_name("gld_intr", &sym
) != -1)
171 if (GELF_ST_TYPE(sym
.st_info
) == STT_FUNC
)
172 gld_intr_addr
= (uintptr_t)sym
.st_value
;
174 if (mdb_readvar(&apic_pir_vect
, "apic_pir_vect") == -1) {