xref: /onnv-gate/usr/src/cmd/mdb/intel/modules/amd_opteron/ao.c (revision 7532:bb6372f778bb)
1*7532SSean.Ye@Sun.COM /*
2*7532SSean.Ye@Sun.COM  * CDDL HEADER START
3*7532SSean.Ye@Sun.COM  *
4*7532SSean.Ye@Sun.COM  * The contents of this file are subject to the terms of the
5*7532SSean.Ye@Sun.COM  * Common Development and Distribution License (the "License").
6*7532SSean.Ye@Sun.COM  * You may not use this file except in compliance with the License.
7*7532SSean.Ye@Sun.COM  *
8*7532SSean.Ye@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7532SSean.Ye@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7532SSean.Ye@Sun.COM  * See the License for the specific language governing permissions
11*7532SSean.Ye@Sun.COM  * and limitations under the License.
12*7532SSean.Ye@Sun.COM  *
13*7532SSean.Ye@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7532SSean.Ye@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7532SSean.Ye@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7532SSean.Ye@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7532SSean.Ye@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7532SSean.Ye@Sun.COM  *
19*7532SSean.Ye@Sun.COM  * CDDL HEADER END
20*7532SSean.Ye@Sun.COM  *
21*7532SSean.Ye@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
22*7532SSean.Ye@Sun.COM  * Use is subject to license terms.
23*7532SSean.Ye@Sun.COM  */
24*7532SSean.Ye@Sun.COM 
25*7532SSean.Ye@Sun.COM #include <mdb/mdb_modapi.h>
26*7532SSean.Ye@Sun.COM #include <amd_opteron/ao.h>
27*7532SSean.Ye@Sun.COM 
28*7532SSean.Ye@Sun.COM #define	ALLBITS	(u_longlong_t)-1
29*7532SSean.Ye@Sun.COM 
30*7532SSean.Ye@Sun.COM static const mdb_bitmask_t ao_nbcfg_bits[] = {
31*7532SSean.Ye@Sun.COM 	{ "SyncOnDramAdrParErrEn", ALLBITS, AMD_NB_CFG_SYNCONDRAMADRPARERREN },
32*7532SSean.Ye@Sun.COM 	{ "NbMcaToMstCpuEn", ALLBITS, AMD_NB_CFG_NBMCATOMSTCPUEN },
33*7532SSean.Ye@Sun.COM 	{ "ReservedBit26", ALLBITS, 0x4000000 },
34*7532SSean.Ye@Sun.COM 	{ "DisPciCfgCpuErrRsp", ALLBITS, AMD_NB_CFG_DISPCICFGCPUERRRSP },
35*7532SSean.Ye@Sun.COM 	{ "IoRdDatErrEn", ALLBITS, AMD_NB_CFG_IORDDATERREN },
36*7532SSean.Ye@Sun.COM 	{ "ChipKillEccEn", ALLBITS, AMD_NB_CFG_CHIPKILLECCEN },
37*7532SSean.Ye@Sun.COM 	{ "EccEn", ALLBITS, AMD_NB_CFG_ECCEN },
38*7532SSean.Ye@Sun.COM 	{ "SyncOnAnyErrEn", ALLBITS, AMD_NB_CFG_SYNCONANYERREN },
39*7532SSean.Ye@Sun.COM 	{ "SyncOnWdogEn", ALLBITS, AMD_NB_CFG_SYNCONWDOGEN },
40*7532SSean.Ye@Sun.COM 	{ "GenCrcErrByte1", ALLBITS, AMD_NB_CFG_GENCRCERRBYTE1 },
41*7532SSean.Ye@Sun.COM 	{ "GenCrcErrByte0", ALLBITS, AMD_NB_CFG_GENCRCERRBYTE0 },
42*7532SSean.Ye@Sun.COM 	/* LdtLinkSel handled separately */
43*7532SSean.Ye@Sun.COM 	/* WdogTmrBaseSel handled separately */
44*7532SSean.Ye@Sun.COM 	/* WdogTmrCntSel handled separately */
45*7532SSean.Ye@Sun.COM 	/* WdogTmrDis handled separately */
46*7532SSean.Ye@Sun.COM 	{ "IoErrDis", ALLBITS, AMD_NB_CFG_IOERRDIS },
47*7532SSean.Ye@Sun.COM 	{ "CpuErrDis", ALLBITS, AMD_NB_CFG_CPUERRDIS },
48*7532SSean.Ye@Sun.COM 	{ "IoMstAbortDis", ALLBITS, AMD_NB_CFG_IOMSTABORTDIS },
49*7532SSean.Ye@Sun.COM 	{ "SyncPktPropDis", ALLBITS, AMD_NB_CFG_SYNCPKTPROPDIS },
50*7532SSean.Ye@Sun.COM 	{ "SyncPktGenDis", ALLBITS, AMD_NB_CFG_SYNCPKTGENDIS },
51*7532SSean.Ye@Sun.COM 	{ "SyncOnUcEccEn", ALLBITS, AMD_NB_CFG_SYNCONUCECCEN },
52*7532SSean.Ye@Sun.COM 	{ "CpuRdDatErrEn", ALLBITS, AMD_NB_CFG_CPURDDATERREN }
53*7532SSean.Ye@Sun.COM };
54*7532SSean.Ye@Sun.COM 
55*7532SSean.Ye@Sun.COM /*ARGSUSED*/
56*7532SSean.Ye@Sun.COM static int
ao_nbcfg_describe(uintptr_t val,uint_t flags,int argc,const mdb_arg_t * argv)57*7532SSean.Ye@Sun.COM ao_nbcfg_describe(uintptr_t val, uint_t flags, int argc, const mdb_arg_t *argv)
58*7532SSean.Ye@Sun.COM {
59*7532SSean.Ye@Sun.COM 	const mdb_bitmask_t *bm;
60*7532SSean.Ye@Sun.COM 	uintptr_t field;
61*7532SSean.Ye@Sun.COM 	int nbits, i;
62*7532SSean.Ye@Sun.COM 
63*7532SSean.Ye@Sun.COM 	if (argc != 0 || !(flags & DCMD_ADDRSPEC))
64*7532SSean.Ye@Sun.COM 		return (DCMD_USAGE);
65*7532SSean.Ye@Sun.COM 
66*7532SSean.Ye@Sun.COM 	for (nbits = 0, bm = ao_nbcfg_bits, i = 0;
67*7532SSean.Ye@Sun.COM 	    i < sizeof (ao_nbcfg_bits) / sizeof (mdb_bitmask_t); i++, bm++) {
68*7532SSean.Ye@Sun.COM 		if (!(val & bm->bm_bits))
69*7532SSean.Ye@Sun.COM 			continue;
70*7532SSean.Ye@Sun.COM 
71*7532SSean.Ye@Sun.COM 		mdb_printf("\t0x%08x  %s\n", bm->bm_bits, bm->bm_name);
72*7532SSean.Ye@Sun.COM 
73*7532SSean.Ye@Sun.COM 		val &= ~bm->bm_bits;
74*7532SSean.Ye@Sun.COM 		nbits++;
75*7532SSean.Ye@Sun.COM 	}
76*7532SSean.Ye@Sun.COM 
77*7532SSean.Ye@Sun.COM 	if ((field = (val & AMD_NB_CFG_LDTLINKSEL_MASK)) != 0) {
78*7532SSean.Ye@Sun.COM 		mdb_printf("\tLdtLinkSel = %d", field >>
79*7532SSean.Ye@Sun.COM 		    AMD_NB_CFG_LDTLINKSEL_SHIFT);
80*7532SSean.Ye@Sun.COM 	}
81*7532SSean.Ye@Sun.COM 
82*7532SSean.Ye@Sun.COM 	if (val & AMD_NB_CFG_WDOGTMRDIS) {
83*7532SSean.Ye@Sun.COM 		mdb_printf("\t0x%08x  %s\n", AMD_NB_CFG_WDOGTMRDIS,
84*7532SSean.Ye@Sun.COM 		    "WdogTmrDis");
85*7532SSean.Ye@Sun.COM 	} else {
86*7532SSean.Ye@Sun.COM 		static const uint_t wdogcounts[] = {
87*7532SSean.Ye@Sun.COM 			4095, 2047, 1023, 511, 255, 127, 63, 31
88*7532SSean.Ye@Sun.COM 		};
89*7532SSean.Ye@Sun.COM 
90*7532SSean.Ye@Sun.COM 		uintptr_t cntfld = (val & AMD_NB_CFG_WDOGTMRCNTSEL_MASK);
91*7532SSean.Ye@Sun.COM 		uintptr_t basefld = (val & AMD_NB_CFG_WDOGTMRBASESEL_MASK);
92*7532SSean.Ye@Sun.COM 		uintptr_t count;
93*7532SSean.Ye@Sun.COM 		int valid = 1;
94*7532SSean.Ye@Sun.COM 		const char *units;
95*7532SSean.Ye@Sun.COM 
96*7532SSean.Ye@Sun.COM 		if (cntfld < sizeof (wdogcounts) / sizeof (uint_t))
97*7532SSean.Ye@Sun.COM 			count = wdogcounts[cntfld];
98*7532SSean.Ye@Sun.COM 		else
99*7532SSean.Ye@Sun.COM 			valid = 0;
100*7532SSean.Ye@Sun.COM 
101*7532SSean.Ye@Sun.COM 		switch (basefld) {
102*7532SSean.Ye@Sun.COM 		case AMD_NB_CFG_WDOGTMRBASESEL_1MS:
103*7532SSean.Ye@Sun.COM 			units = "ms";
104*7532SSean.Ye@Sun.COM 			break;
105*7532SSean.Ye@Sun.COM 		case AMD_NB_CFG_WDOGTMRBASESEL_1US:
106*7532SSean.Ye@Sun.COM 			units = "us";
107*7532SSean.Ye@Sun.COM 			break;
108*7532SSean.Ye@Sun.COM 		case AMD_NB_CFG_WDOGTMRBASESEL_5NS:
109*7532SSean.Ye@Sun.COM 			count *= 5;
110*7532SSean.Ye@Sun.COM 			units = "ns";
111*7532SSean.Ye@Sun.COM 			break;
112*7532SSean.Ye@Sun.COM 		default:
113*7532SSean.Ye@Sun.COM 			units = " (unknown units)";
114*7532SSean.Ye@Sun.COM 			break;
115*7532SSean.Ye@Sun.COM 		}
116*7532SSean.Ye@Sun.COM 
117*7532SSean.Ye@Sun.COM 		if (valid) {
118*7532SSean.Ye@Sun.COM 			mdb_printf("\tWatchdog timeout: %u%s\n", count,
119*7532SSean.Ye@Sun.COM 			    units);
120*7532SSean.Ye@Sun.COM 		} else {
121*7532SSean.Ye@Sun.COM 			mdb_printf("\tInvalid Watchdog: Count %u, Base %u\n",
122*7532SSean.Ye@Sun.COM 			    cntfld, basefld);
123*7532SSean.Ye@Sun.COM 		}
124*7532SSean.Ye@Sun.COM 	}
125*7532SSean.Ye@Sun.COM 
126*7532SSean.Ye@Sun.COM 	return (DCMD_OK);
127*7532SSean.Ye@Sun.COM }
128*7532SSean.Ye@Sun.COM 
129*7532SSean.Ye@Sun.COM static const char *ao_scrub_rate[] = {
130*7532SSean.Ye@Sun.COM 	"Do not scrub",		/* 0b00000 */
131*7532SSean.Ye@Sun.COM 	"40.0 nanosec",		/* 0b00001 */
132*7532SSean.Ye@Sun.COM 	"80.0 nanosec",		/* 0b00010 */
133*7532SSean.Ye@Sun.COM 	"160.0 nanosec",	/* 0b00011 */
134*7532SSean.Ye@Sun.COM 	"320.0 nanosec",	/* 0b00100 */
135*7532SSean.Ye@Sun.COM 	"640.0 nanosec",	/* 0b00101 */
136*7532SSean.Ye@Sun.COM 	"1.28 microsec",	/* 0b00110 */
137*7532SSean.Ye@Sun.COM 	"2.56 microsec",	/* 0b00111 */
138*7532SSean.Ye@Sun.COM 	"5.12 microsec",	/* 0b01000 */
139*7532SSean.Ye@Sun.COM 	"10.2 microsec",	/* 0b01001 */
140*7532SSean.Ye@Sun.COM 	"20.5 microsec",	/* 0b01010 */
141*7532SSean.Ye@Sun.COM 	"41.0 microsec",	/* 0b01011 */
142*7532SSean.Ye@Sun.COM 	"81.9 microsec",	/* 0b01100 */
143*7532SSean.Ye@Sun.COM 	"163.8 microsec",	/* 0b01101 */
144*7532SSean.Ye@Sun.COM 	"327.7 microsec",	/* 0b01110 */
145*7532SSean.Ye@Sun.COM 	"655.4 microsec",	/* 0b01111 */
146*7532SSean.Ye@Sun.COM 	"1.31 millsec",		/* 0b10000 */
147*7532SSean.Ye@Sun.COM 	"2.62 millsec",		/* 0b10001 */
148*7532SSean.Ye@Sun.COM 	"5.24 millsec",		/* 0b10010 */
149*7532SSean.Ye@Sun.COM 	"10.49 millsec",	/* 0b10011 */
150*7532SSean.Ye@Sun.COM 	"20.97 millsec",	/* 0b10100 */
151*7532SSean.Ye@Sun.COM 	"42.00 millsec",	/* 0b10101 */
152*7532SSean.Ye@Sun.COM 	"84.00 millsec",	/* 0b10110 */
153*7532SSean.Ye@Sun.COM };
154*7532SSean.Ye@Sun.COM 
155*7532SSean.Ye@Sun.COM #define	SCRUBCODE(val, low) ((val) >> low & 0x1f)
156*7532SSean.Ye@Sun.COM 
157*7532SSean.Ye@Sun.COM #define	SCRUBSTR(val, low) \
158*7532SSean.Ye@Sun.COM 	(SCRUBCODE(val, low) < sizeof (ao_scrub_rate) / sizeof (char *) ? \
159*7532SSean.Ye@Sun.COM 	ao_scrub_rate[SCRUBCODE(val, low)] : "reserved value!")
160*7532SSean.Ye@Sun.COM 
161*7532SSean.Ye@Sun.COM /*ARGSUSED*/
162*7532SSean.Ye@Sun.COM static int
ao_scrubctl_describe(uintptr_t val,uint_t flags,int argc,const mdb_arg_t * argv)163*7532SSean.Ye@Sun.COM ao_scrubctl_describe(uintptr_t val, uint_t flags, int argc,
164*7532SSean.Ye@Sun.COM     const mdb_arg_t *argv)
165*7532SSean.Ye@Sun.COM {
166*7532SSean.Ye@Sun.COM 	if (argc != 0 || !(flags & DCMD_ADDRSPEC))
167*7532SSean.Ye@Sun.COM 		return (DCMD_USAGE);
168*7532SSean.Ye@Sun.COM 
169*7532SSean.Ye@Sun.COM 	mdb_printf("\tDcacheScrub: %s\n\t    L2Scrub: %s\n\t  DramScrub: %s\n",
170*7532SSean.Ye@Sun.COM 	    SCRUBSTR(val, 16), SCRUBSTR(val, 8), SCRUBSTR(val, 0));
171*7532SSean.Ye@Sun.COM 
172*7532SSean.Ye@Sun.COM 	return (DCMD_OK);
173*7532SSean.Ye@Sun.COM }
174*7532SSean.Ye@Sun.COM 
175*7532SSean.Ye@Sun.COM /*ARGSUSED*/
176*7532SSean.Ye@Sun.COM static int
ao_sparectl_describe(uintptr_t val,uint_t flags,int argc,const mdb_arg_t * argv)177*7532SSean.Ye@Sun.COM ao_sparectl_describe(uintptr_t val, uint_t flags, int argc,
178*7532SSean.Ye@Sun.COM     const mdb_arg_t *argv)
179*7532SSean.Ye@Sun.COM {
180*7532SSean.Ye@Sun.COM 	const char *itypes[] = {
181*7532SSean.Ye@Sun.COM 		"No Interrupt",	/* 0b00 */
182*7532SSean.Ye@Sun.COM 		"Reserved",	/* 0b01 */
183*7532SSean.Ye@Sun.COM 		"SMI",		/* 0b10 */
184*7532SSean.Ye@Sun.COM 		"Reserved",	/* 0b11 */
185*7532SSean.Ye@Sun.COM 	};
186*7532SSean.Ye@Sun.COM 
187*7532SSean.Ye@Sun.COM 	if (argc != 0 || !(flags & DCMD_ADDRSPEC))
188*7532SSean.Ye@Sun.COM 		return (DCMD_USAGE);
189*7532SSean.Ye@Sun.COM 
190*7532SSean.Ye@Sun.COM 	mdb_printf(
191*7532SSean.Ye@Sun.COM 	    "\t  EccErrInt: %s\n"
192*7532SSean.Ye@Sun.COM 	    "\tSwapDoneInt: %s\n"
193*7532SSean.Ye@Sun.COM 	    "\t  BadDramCs: %d\n"
194*7532SSean.Ye@Sun.COM 	    "\t   SwapDone: %s\n"
195*7532SSean.Ye@Sun.COM 	    "\t     SwapEn: %s\n",
196*7532SSean.Ye@Sun.COM 	    itypes[val >> 14 & 0x3],
197*7532SSean.Ye@Sun.COM 	    itypes[val >> 12 & 0x3],
198*7532SSean.Ye@Sun.COM 	    val >> 4 & 0x7,
199*7532SSean.Ye@Sun.COM 	    val & 0x2 ? "Yes" : "No",
200*7532SSean.Ye@Sun.COM 	    val & 0x1 ? "Yes" : "No");
201*7532SSean.Ye@Sun.COM 
202*7532SSean.Ye@Sun.COM 	return (DCMD_OK);
203*7532SSean.Ye@Sun.COM }
204*7532SSean.Ye@Sun.COM 
205*7532SSean.Ye@Sun.COM static const char *ao_mcactl_dc[] = {
206*7532SSean.Ye@Sun.COM 	"ECCI (Single-bit ECC Data Errors)",
207*7532SSean.Ye@Sun.COM 	"ECCM (Multi-bit ECC Data Errors)",
208*7532SSean.Ye@Sun.COM 	"DECC (Data Array ECC Errors)",
209*7532SSean.Ye@Sun.COM 	"DMTP (Main Tag Array Parity Errors)",
210*7532SSean.Ye@Sun.COM 	"DSTP (Snoop Tag Array Parity Errors)",
211*7532SSean.Ye@Sun.COM 	"L1TP (L1 TLB Parity Errors)",
212*7532SSean.Ye@Sun.COM 	"L2TP (L2 TLB Parity Errors)",
213*7532SSean.Ye@Sun.COM };
214*7532SSean.Ye@Sun.COM 
215*7532SSean.Ye@Sun.COM static const char *ao_mcactl_ic[] = {
216*7532SSean.Ye@Sun.COM 	"ECCI (Single-bit ECC data errors)",
217*7532SSean.Ye@Sun.COM 	"ECCM (Multi-bit ECC data errors)",
218*7532SSean.Ye@Sun.COM 	"IDP (Data array parity errors)",
219*7532SSean.Ye@Sun.COM 	"IMTP (Main tag array parity errors)",
220*7532SSean.Ye@Sun.COM 	"ISTP (Snoop tag array parity errors)",
221*7532SSean.Ye@Sun.COM 	"L1TP (L1 TLB Parity Errors)",
222*7532SSean.Ye@Sun.COM 	"L2TP (L2 TLB Parity Errors)",
223*7532SSean.Ye@Sun.COM 	NULL,	/* reserved */
224*7532SSean.Ye@Sun.COM 	NULL,	/* reserved */
225*7532SSean.Ye@Sun.COM 	"RDDE (Read Data Errors)",
226*7532SSean.Ye@Sun.COM };
227*7532SSean.Ye@Sun.COM 
228*7532SSean.Ye@Sun.COM static const char *ao_mcactl_bu[] = {
229*7532SSean.Ye@Sun.COM 	"S_RDE_HP (System read data hardware prefetch)",
230*7532SSean.Ye@Sun.COM 	"S_RDE_TLB (System read data TLB reload)",
231*7532SSean.Ye@Sun.COM 	"S_RDE_ALL (All system read data)",
232*7532SSean.Ye@Sun.COM 	"S_ECC1_TLB (System data 1-bit ECC TLB reload)",
233*7532SSean.Ye@Sun.COM 	"S_ECC1_HP (System data 1-bit ECC hardware prefetch)",
234*7532SSean.Ye@Sun.COM 	"S_ECCM_TLB (System data multi-bit ECC TLB reload)",
235*7532SSean.Ye@Sun.COM 	"S_ECCM_HP (System data multi-bit ECC hardware prefetch)",
236*7532SSean.Ye@Sun.COM 	"L2T_PAR_ICDC (L2 tag array parity IC or DC fetch)",
237*7532SSean.Ye@Sun.COM 	"L2T_PAR_TLB (L2 tag array parity TLB reload)",
238*7532SSean.Ye@Sun.COM 	"L2T_PAR_SNP (L2 tag array parity snoop)",
239*7532SSean.Ye@Sun.COM 	"L2T_PAR_CPB (L2 tag array parity copyback)",
240*7532SSean.Ye@Sun.COM 	"L2T_PAR_SCR (L2 tag array parity scrub)",
241*7532SSean.Ye@Sun.COM 	"L2D_ECC1_TLB (L2 data array 1-bit ECC TLB reload)",
242*7532SSean.Ye@Sun.COM 	"L2D_ECC1_SNP (L2 data array 1-bit ECC snoop)",
243*7532SSean.Ye@Sun.COM 	"L2D_ECC1_CPB (L2 data array 1-bit ECC copyback)",
244*7532SSean.Ye@Sun.COM 	"L2D_ECCM_TLB (L2 data array multi-bit ECC TLB reload)",
245*7532SSean.Ye@Sun.COM 	"L2D_ECCM_SNP (L2 data array multi-bit ECC snoop)",
246*7532SSean.Ye@Sun.COM 	"L2D_ECCM_CPB (L2 data array multi-bit ECC copyback)",
247*7532SSean.Ye@Sun.COM 	"L2T_ECC1_SCR (L2 tag array 1-bit ECC Scrub)",
248*7532SSean.Ye@Sun.COM 	"L2T_ECCM_SCR (L2 tag array multi-bit ECC Scrub)",
249*7532SSean.Ye@Sun.COM };
250*7532SSean.Ye@Sun.COM 
251*7532SSean.Ye@Sun.COM static const char *ao_mcactl_ls[] = {
252*7532SSean.Ye@Sun.COM 	"S_RDE_L (Read Data Errors on Load)",
253*7532SSean.Ye@Sun.COM 	"S_RDE_S (Read Data Errors on Store)",
254*7532SSean.Ye@Sun.COM };
255*7532SSean.Ye@Sun.COM 
256*7532SSean.Ye@Sun.COM static const char *ao_mcactl_nb[] = {
257*7532SSean.Ye@Sun.COM 	"CorrEccEn (Correctable ECC Error Reporting Enable)",
258*7532SSean.Ye@Sun.COM 	"UnCorrEccEn (Uncorrectable ECC Error Reporting Enable)",
259*7532SSean.Ye@Sun.COM 	"CrcErr0En (HT Link 0 CRC Error Reporting Enable)",
260*7532SSean.Ye@Sun.COM 	"CrcErr1En (HT Link 1 CRC Error Reporting Enable)",
261*7532SSean.Ye@Sun.COM 	"CrcErr2En (HT Link 2 CRC Error Reporting Enable)",
262*7532SSean.Ye@Sun.COM 	"SyncPkt0En (HT Link 0 Sync Packet Error Reporting Enable)",
263*7532SSean.Ye@Sun.COM 	"SyncPkt1En (HT Link 1 Sync Packet Error Reporting Enable)",
264*7532SSean.Ye@Sun.COM 	"SyncPkt2En (HT Link 2 Sync Packet Error Reporting Enable)",
265*7532SSean.Ye@Sun.COM 	"MstrAbrtEn (Master Abort Error Reporting Enable)",
266*7532SSean.Ye@Sun.COM 	"TgtAbrtEn (Target Abort Error Reporting Enable)",
267*7532SSean.Ye@Sun.COM 	"GartTblWkEn (GART Table Walk Error Reporting Enable)",
268*7532SSean.Ye@Sun.COM 	"AtomicRMWEn (Atomic Read-Modify-Write Error Reporting Enable)",
269*7532SSean.Ye@Sun.COM 	"WchDogTmrEn (Watchdog Timer Error Reporting Enable)",
270*7532SSean.Ye@Sun.COM 	NULL,	/* reserved */
271*7532SSean.Ye@Sun.COM 	NULL,	/* reserved */
272*7532SSean.Ye@Sun.COM 	NULL,	/* reserved */
273*7532SSean.Ye@Sun.COM 	NULL,	/* reserved */
274*7532SSean.Ye@Sun.COM 	NULL,	/* reserved */
275*7532SSean.Ye@Sun.COM 	"DramParEn (DRAM Parity Error Reporting enable)",
276*7532SSean.Ye@Sun.COM };
277*7532SSean.Ye@Sun.COM 
278*7532SSean.Ye@Sun.COM static const struct ao_mcactl {
279*7532SSean.Ye@Sun.COM 	const char *bank_name;
280*7532SSean.Ye@Sun.COM 	const char **bank_ctlbits;
281*7532SSean.Ye@Sun.COM 	int bank_tblsz;
282*7532SSean.Ye@Sun.COM } ao_mcactls[] = {
283*7532SSean.Ye@Sun.COM 	{ "dc", &ao_mcactl_dc[0], sizeof (ao_mcactl_dc) / sizeof (char *) },
284*7532SSean.Ye@Sun.COM 	{ "ic", &ao_mcactl_ic[0], sizeof (ao_mcactl_ic) / sizeof (char *) },
285*7532SSean.Ye@Sun.COM 	{ "bu", &ao_mcactl_bu[0], sizeof (ao_mcactl_bu) / sizeof (char *) },
286*7532SSean.Ye@Sun.COM 	{ "ls", &ao_mcactl_ls[0], sizeof (ao_mcactl_ls) / sizeof (char *) },
287*7532SSean.Ye@Sun.COM 	{ "nb", &ao_mcactl_nb[0], sizeof (ao_mcactl_nb) / sizeof (char *) }
288*7532SSean.Ye@Sun.COM };
289*7532SSean.Ye@Sun.COM 
290*7532SSean.Ye@Sun.COM #define	AO_MCI_CTL	0x0
291*7532SSean.Ye@Sun.COM #define	AO_MCI_MASK	0x1
292*7532SSean.Ye@Sun.COM 
293*7532SSean.Ye@Sun.COM static int
ao_mci_ctlmask_common(uintptr_t val,uint_t flags,int argc,const mdb_arg_t * argv,int which)294*7532SSean.Ye@Sun.COM ao_mci_ctlmask_common(uintptr_t val, uint_t flags, int argc,
295*7532SSean.Ye@Sun.COM     const mdb_arg_t *argv, int which)
296*7532SSean.Ye@Sun.COM {
297*7532SSean.Ye@Sun.COM 	uint64_t bank;
298*7532SSean.Ye@Sun.COM 	const char *bankname = NULL;
299*7532SSean.Ye@Sun.COM 	int i;
300*7532SSean.Ye@Sun.COM 
301*7532SSean.Ye@Sun.COM 	if (argc != 2 || !(flags & DCMD_ADDRSPEC))
302*7532SSean.Ye@Sun.COM 		return (DCMD_USAGE);
303*7532SSean.Ye@Sun.COM 
304*7532SSean.Ye@Sun.COM 	if (mdb_getopts(argc, argv,
305*7532SSean.Ye@Sun.COM 	    't', MDB_OPT_STR, &bankname, NULL) != 2)
306*7532SSean.Ye@Sun.COM 		return (DCMD_USAGE);
307*7532SSean.Ye@Sun.COM 
308*7532SSean.Ye@Sun.COM 	for (i = 0; i < AMD_MCA_BANK_COUNT; i++) {
309*7532SSean.Ye@Sun.COM 		if (strncmp(bankname, ao_mcactls[i].bank_name,
310*7532SSean.Ye@Sun.COM 		    2) == 0) {
311*7532SSean.Ye@Sun.COM 			bank = i;
312*7532SSean.Ye@Sun.COM 			break;
313*7532SSean.Ye@Sun.COM 		}
314*7532SSean.Ye@Sun.COM 	}
315*7532SSean.Ye@Sun.COM 
316*7532SSean.Ye@Sun.COM 	if (i == AMD_MCA_BANK_COUNT) {
317*7532SSean.Ye@Sun.COM 		mdb_warn("Valid bank names: dc, ic, bu, ls, nb\n");
318*7532SSean.Ye@Sun.COM 		return (DCMD_ERR);
319*7532SSean.Ye@Sun.COM 	}
320*7532SSean.Ye@Sun.COM 
321*7532SSean.Ye@Sun.COM 	mdb_printf("Reporting %s for %s:\n", which == AO_MCI_CTL ? "enables" :
322*7532SSean.Ye@Sun.COM 	    "masks", ao_mcactls[bank].bank_name);
323*7532SSean.Ye@Sun.COM 	mdb_printf("%3s %4s %s\n", "Bit", "Set?", "Description");
324*7532SSean.Ye@Sun.COM 
325*7532SSean.Ye@Sun.COM 	for (i = 0; i < 63; i++) {
326*7532SSean.Ye@Sun.COM 		int set = val & 0x1ULL << i;
327*7532SSean.Ye@Sun.COM 		int inrange = i < ao_mcactls[bank].bank_tblsz;
328*7532SSean.Ye@Sun.COM 		const char *desc = ao_mcactls[bank].bank_ctlbits[i];
329*7532SSean.Ye@Sun.COM 
330*7532SSean.Ye@Sun.COM 		if (inrange) {
331*7532SSean.Ye@Sun.COM 			int known = desc != NULL;
332*7532SSean.Ye@Sun.COM 
333*7532SSean.Ye@Sun.COM 			mdb_printf("%2d  %4s ", i, set ? "Yes" : "- ");
334*7532SSean.Ye@Sun.COM 			if (known)
335*7532SSean.Ye@Sun.COM 				mdb_printf("%s\n", desc);
336*7532SSean.Ye@Sun.COM 			else
337*7532SSean.Ye@Sun.COM 				mdb_printf("reserved%s\n",
338*7532SSean.Ye@Sun.COM 				    set ? " - but set!" : "");
339*7532SSean.Ye@Sun.COM 		} else if (set) {
340*7532SSean.Ye@Sun.COM 				mdb_printf("%2d  %4s Reserved - but set!\n",
341*7532SSean.Ye@Sun.COM 				    i, "Yes");
342*7532SSean.Ye@Sun.COM 		}
343*7532SSean.Ye@Sun.COM 	}
344*7532SSean.Ye@Sun.COM 
345*7532SSean.Ye@Sun.COM 	return (DCMD_OK);
346*7532SSean.Ye@Sun.COM }
347*7532SSean.Ye@Sun.COM 
348*7532SSean.Ye@Sun.COM /*ARGSUSED3*/
349*7532SSean.Ye@Sun.COM static int
ao_mci_ctl(uintptr_t val,uint_t flags,int argc,const mdb_arg_t * argv)350*7532SSean.Ye@Sun.COM ao_mci_ctl(uintptr_t val, uint_t flags, int argc, const mdb_arg_t *argv)
351*7532SSean.Ye@Sun.COM {
352*7532SSean.Ye@Sun.COM 	return (ao_mci_ctlmask_common(val, flags, argc, argv, AO_MCI_CTL));
353*7532SSean.Ye@Sun.COM }
354*7532SSean.Ye@Sun.COM 
355*7532SSean.Ye@Sun.COM /*ARGSUSED3*/
356*7532SSean.Ye@Sun.COM static int
ao_mci_mask(uintptr_t val,uint_t flags,int argc,const mdb_arg_t * argv)357*7532SSean.Ye@Sun.COM ao_mci_mask(uintptr_t val, uint_t flags, int argc, const mdb_arg_t *argv)
358*7532SSean.Ye@Sun.COM {
359*7532SSean.Ye@Sun.COM 	return (ao_mci_ctlmask_common(val, flags, argc, argv, AO_MCI_MASK));
360*7532SSean.Ye@Sun.COM }
361*7532SSean.Ye@Sun.COM 
362*7532SSean.Ye@Sun.COM static const mdb_dcmd_t dcmds[] = {
363*7532SSean.Ye@Sun.COM 	{ "ao_nbcfg", ":", "decode Northbridge config bits",
364*7532SSean.Ye@Sun.COM 	    ao_nbcfg_describe },
365*7532SSean.Ye@Sun.COM 	{ "ao_scrubctl", ":", "decode Scrub Control Register",
366*7532SSean.Ye@Sun.COM 	    ao_scrubctl_describe },
367*7532SSean.Ye@Sun.COM 	{ "ao_sparectl", ":", "decode Online Spare Control Register",
368*7532SSean.Ye@Sun.COM 	    ao_sparectl_describe },
369*7532SSean.Ye@Sun.COM 	{ "ao_mci_ctl", ":  -t <dc|ic|bu|ls|nb>",
370*7532SSean.Ye@Sun.COM 	    "decode MCi_CTL", ao_mci_ctl },
371*7532SSean.Ye@Sun.COM 	{ "ao_mci_mask", ":  -t <dc|ic|bu|ls|nb>",
372*7532SSean.Ye@Sun.COM 	    "decode MCi_MASK", ao_mci_mask },
373*7532SSean.Ye@Sun.COM 	{ NULL }
374*7532SSean.Ye@Sun.COM };
375*7532SSean.Ye@Sun.COM 
376*7532SSean.Ye@Sun.COM static const mdb_walker_t walkers[] = {
377*7532SSean.Ye@Sun.COM 	{ NULL }
378*7532SSean.Ye@Sun.COM };
379*7532SSean.Ye@Sun.COM 
380*7532SSean.Ye@Sun.COM static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
381*7532SSean.Ye@Sun.COM 
382*7532SSean.Ye@Sun.COM const mdb_modinfo_t *
_mdb_init(void)383*7532SSean.Ye@Sun.COM _mdb_init(void)
384*7532SSean.Ye@Sun.COM {
385*7532SSean.Ye@Sun.COM 	return (&modinfo);
386*7532SSean.Ye@Sun.COM }
387