1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include "intr_common.h"
26
27 #ifdef _KMDB
28
29 /* Macros for reading/writing the IOAPIC RDT entries */
30 #define APIC_READ_IOAPIC_RDT_ENTRY_LOW_DWORD(ioapic_ix, ipin) \
31 apic_ioapic_read(ioapic_ix, APIC_RDT_CMD + (2 * (ipin)))
32
33 #define APIC_READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(ioapic_ix, ipin) \
34 apic_ioapic_read(ioapic_ix, APIC_RDT_CMD2 + (2 * (ipin)))
35
36 static uint32_t *ioapic_adr[MAX_IO_APIC];
37
38 static uint32_t
apic_ioapic_read(int ioapic_ix,uint32_t reg)39 apic_ioapic_read(int ioapic_ix, uint32_t reg)
40 {
41 volatile uint32_t *ioapic;
42
43 ioapic = ioapic_adr[ioapic_ix];
44 ioapic[APIC_IO_REG] = reg;
45 return (ioapic[APIC_IO_DATA]);
46 }
47
48 /*
49 * ioapic dcmd - Print out the ioapic registers, nicely formatted.
50 */
51 /*ARGSUSED*/
52 int
ioapic(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)53 ioapic(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
54 {
55 uint32_t apic_io_max;
56 int reg;
57 int reg_max;
58 int i;
59
60
61 if ((flags & DCMD_ADDRSPEC) || argc != 0)
62 return (DCMD_USAGE);
63
64 if (mdb_readvar(&ioapic_adr, "apicioadr") == -1) {
65 /*
66 * If the mdb_warn string does not end in a \n, mdb will
67 * automatically append the reason for the failure.
68 */
69 mdb_warn("failed to read ioapicadr");
70 return (DCMD_ERR);
71 }
72
73 if (mdb_readvar(&apic_io_max, "apic_io_max") == -1) {
74 /*
75 * If the mdb_warn string does not end in a \n, mdb will
76 * automatically append the reason for the failure.
77 */
78 mdb_warn("failed to read apic_io_max");
79 return (DCMD_ERR);
80 }
81
82 mdb_printf("ioapicadr\t%p\n", ioapic_adr);
83
84 for (i = 0; i < apic_io_max; i++) {
85 /* Bits 23-16 define the maximum redirection entries */
86 reg_max = apic_ioapic_read(i, APIC_VERS_CMD);
87 reg_max = (reg_max >> 16) & 0xff;
88
89 mdb_printf("%4s %8s %8s\n", "reg", "high", " low");
90 for (reg = 0; reg <= reg_max; reg++) {
91 uint32_t high, low;
92
93 high = APIC_READ_IOAPIC_RDT_ENTRY_HIGH_DWORD(i, reg);
94 low = APIC_READ_IOAPIC_RDT_ENTRY_LOW_DWORD(i, reg);
95
96 mdb_printf("%2d %8x %8x\n", reg, high, low);
97 }
98
99 mdb_printf("\n");
100
101 }
102
103 return (DCMD_OK);
104 }
105
106
107 /*
108 * apic dcmd - Print out the apic registers, nicely formatted.
109 */
110 /*ARGSUSED*/
111 int
apic(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)112 apic(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
113 {
114 uint32_t *papic;
115
116 if ((flags & DCMD_ADDRSPEC) || argc != 0)
117 return (DCMD_USAGE);
118
119 if (mdb_readvar(&papic, "apicadr") == -1) {
120 /*
121 * If the mdb_warn string does not end in a \n, mdb will
122 * automatically append the reason for the failure.
123 */
124 mdb_warn("failed to read apicadr");
125 return (DCMD_ERR);
126 }
127
128 mdb_printf("apicadr\t%p\n", papic);
129 mdb_printf("as_task_reg\t%x\n", papic[APIC_TASK_REG]);
130 mdb_printf("as_dest_reg\t%x\n", papic[APIC_DEST_REG]);
131 mdb_printf("as_format_reg\t%x\n", papic[APIC_FORMAT_REG]);
132 mdb_printf("as_local_timer\t%x\n", papic[APIC_LOCAL_TIMER]);
133 mdb_printf("as_pcint_vect\t%x\n", papic[APIC_PCINT_VECT]);
134 mdb_printf("as_int_vect0\t%x\n", papic[APIC_INT_VECT0]);
135 mdb_printf("as_int_vect1\t%x\n", papic[APIC_INT_VECT1]);
136 mdb_printf("as_err_vect\t%x\n", papic[APIC_ERR_VECT]);
137 mdb_printf("as_init_count\t%x\n", papic[APIC_INIT_COUNT]);
138 mdb_printf("as_divide_reg\t%x\n", papic[APIC_DIVIDE_REG]);
139 mdb_printf("as_spur_int_reg\t%x\n", papic[APIC_SPUR_INT_REG]);
140
141 return (DCMD_OK);
142 }
143
144 #endif /* _KMDB */
145