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