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