xref: /titanic_44/usr/src/uts/sun4/sys/errclassify.h (revision 6dfee4834394825da35b977ca71cdc965bc7b6a4)
1*6dfee483Stsien /*
2*6dfee483Stsien  * CDDL HEADER START
3*6dfee483Stsien  *
4*6dfee483Stsien  * The contents of this file are subject to the terms of the
5*6dfee483Stsien  * Common Development and Distribution License, Version 1.0 only
6*6dfee483Stsien  * (the "License").  You may not use this file except in compliance
7*6dfee483Stsien  * with the License.
8*6dfee483Stsien  *
9*6dfee483Stsien  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*6dfee483Stsien  * or http://www.opensolaris.org/os/licensing.
11*6dfee483Stsien  * See the License for the specific language governing permissions
12*6dfee483Stsien  * and limitations under the License.
13*6dfee483Stsien  *
14*6dfee483Stsien  * When distributing Covered Code, include this CDDL HEADER in each
15*6dfee483Stsien  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*6dfee483Stsien  * If applicable, add the following below this CDDL HEADER, with the
17*6dfee483Stsien  * fields enclosed by brackets "[]" replaced with your own identifying
18*6dfee483Stsien  * information: Portions Copyright [yyyy] [name of copyright owner]
19*6dfee483Stsien  *
20*6dfee483Stsien  * CDDL HEADER END
21*6dfee483Stsien  */
22*6dfee483Stsien /*
23*6dfee483Stsien  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*6dfee483Stsien  * Use is subject to license terms.
25*6dfee483Stsien  */
26*6dfee483Stsien 
27*6dfee483Stsien #ifndef	_SYS_ERRCLASSIFY_H
28*6dfee483Stsien #define	_SYS_ERRCLASSIFY_H
29*6dfee483Stsien 
30*6dfee483Stsien #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*6dfee483Stsien 
32*6dfee483Stsien #ifdef	__cplusplus
33*6dfee483Stsien extern "C" {
34*6dfee483Stsien #endif
35*6dfee483Stsien 
36*6dfee483Stsien #ifndef	_ASM
37*6dfee483Stsien 
38*6dfee483Stsien #include <sys/errorq.h>
39*6dfee483Stsien 
40*6dfee483Stsien /*
41*6dfee483Stsien  * Note that the order in the following must be kept in sync with that
42*6dfee483Stsien  * in the sun4u DE cmd_memerr.c and with the cetypes array of us3_common.c
43*6dfee483Stsien  */
44*6dfee483Stsien typedef enum {
45*6dfee483Stsien 	/*
46*6dfee483Stsien 	 * The first byte (256 values) is for type and can be sequential.
47*6dfee483Stsien 	 */
48*6dfee483Stsien 	CE_DISP_UNKNOWN,
49*6dfee483Stsien 	CE_DISP_INTERMITTENT,
50*6dfee483Stsien 	CE_DISP_POSS_PERS,
51*6dfee483Stsien 	CE_DISP_PERS,
52*6dfee483Stsien 	CE_DISP_LEAKY,
53*6dfee483Stsien 	CE_DISP_POSS_STICKY,
54*6dfee483Stsien 	CE_DISP_STICKY,
55*6dfee483Stsien 	/*
56*6dfee483Stsien 	 * The next byte encodes the next action as a bitmask
57*6dfee483Stsien 	 */
58*6dfee483Stsien 	CE_ACT_DONE = 0x100,
59*6dfee483Stsien 	CE_ACT_LKYCHK = 0x200,
60*6dfee483Stsien 	CE_ACT_PTNRCHK = 0x400,
61*6dfee483Stsien 	/*
62*6dfee483Stsien 	 * Keep this as the last entry.  Not all entries of the type lookup
63*6dfee483Stsien 	 * table are used and this value is the "uninitialized" pattern.
64*6dfee483Stsien 	 */
65*6dfee483Stsien 	CE_DISP_BAD = 0xbadbad1
66*6dfee483Stsien } ce_dispact_t;
67*6dfee483Stsien 
68*6dfee483Stsien /*
69*6dfee483Stsien  * Extract disposition or action from a ce_dispact_t
70*6dfee483Stsien  */
71*6dfee483Stsien #define	CE_DISP(dispact) \
72*6dfee483Stsien 	(dispact & 0xff)
73*6dfee483Stsien #define	CE_ACT(dispact) \
74*6dfee483Stsien 	(dispact & 0xff00)
75*6dfee483Stsien 
76*6dfee483Stsien /*
77*6dfee483Stsien  * Short string names for classification types.
78*6dfee483Stsien  */
79*6dfee483Stsien #define	CE_DISP_DESC_U		"U"
80*6dfee483Stsien #define	CE_DISP_DESC_I		"I"
81*6dfee483Stsien #define	CE_DISP_DESC_PP		"PP"
82*6dfee483Stsien #define	CE_DISP_DESC_P		"P"
83*6dfee483Stsien #define	CE_DISP_DESC_L		"L"
84*6dfee483Stsien #define	CE_DISP_DESC_PS		"PS"
85*6dfee483Stsien #define	CE_DISP_DESC_S		"S"
86*6dfee483Stsien 
87*6dfee483Stsien /*
88*6dfee483Stsien  * Various sun4u CPU types use different Ecache state encodings.
89*6dfee483Stsien  * For CE classification the following unified scheme is used.
90*6dfee483Stsien  */
91*6dfee483Stsien #define	EC_STATE_M		0x4
92*6dfee483Stsien #define	EC_STATE_O		0x3
93*6dfee483Stsien #define	EC_STATE_E		0x2
94*6dfee483Stsien #define	EC_STATE_S		0x1
95*6dfee483Stsien #define	EC_STATE_I		0x0
96*6dfee483Stsien 
97*6dfee483Stsien /*
98*6dfee483Stsien  * Macros to generate the initial CE classification table (in both kernel and
99*6dfee483Stsien  * userland).  An array size CE_INITDISPTBL_SIZE of ce_dispact_t should be
100*6dfee483Stsien  * defined and passed by name to ECC_INITDISPTBL_POPULATE which will populate
101*6dfee483Stsien  * the array slots that are use and set the unused ones to CE_DISP_BAD.
102*6dfee483Stsien  *
103*6dfee483Stsien  * To perform a lookup use CE_DISPACT passing the name of the same
104*6dfee483Stsien  * array and the afarmatch, ecstate, ce1 and ce2 information.
105*6dfee483Stsien  *
106*6dfee483Stsien  * Other macros defined here should not be used directly.
107*6dfee483Stsien  *
108*6dfee483Stsien  * CE_INITDISPTBL_INDEX will generate an index as follows:
109*6dfee483Stsien  *
110*6dfee483Stsien  *	<5>	afar match
111*6dfee483Stsien  *	<4:2>	line state
112*6dfee483Stsien  *	<1>	ce2 - CE seen on lddphys of scrub algorithm (after writeback)
113*6dfee483Stsien  *	<0>	ce1 - CE seen on CASXA of scrub algorithm (before writeback)
114*6dfee483Stsien  *
115*6dfee483Stsien  * When the afar does not match line state must be zero.
116*6dfee483Stsien  */
117*6dfee483Stsien #define	CE_INITDISPTBL_SIZE	(1 << 6)
118*6dfee483Stsien #define	CE_INITDISPTBL_INDEX(afarmatch, ecstate, ce1, ce2) \
119*6dfee483Stsien 	((afarmatch) << 5 | (ecstate) << 2 | (ce2) << 1 | (ce1))
120*6dfee483Stsien 
121*6dfee483Stsien #define	CE_DISPACT(array, afarmatch, ecstate, ce1, ce2) \
122*6dfee483Stsien 	(array[CE_INITDISPTBL_INDEX(afarmatch, ecstate, ce1, ce2)])
123*6dfee483Stsien 
124*6dfee483Stsien #define	CE_INITDISPTBL_POPULATE(a)					\
125*6dfee483Stsien {									\
126*6dfee483Stsien 	int i;								\
127*6dfee483Stsien 	for (i = 0; i < CE_INITDISPTBL_SIZE; ++i)			\
128*6dfee483Stsien 		a[i] = CE_DISP_BAD;					\
129*6dfee483Stsien /*									\
130*6dfee483Stsien  *	   afar  ec	      ce1  ce2	initial disp and next action	\
131*6dfee483Stsien  *	  match  state							\
132*6dfee483Stsien  */									\
133*6dfee483Stsien CE_DISPACT(a, 0, 0,		0, 0) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
134*6dfee483Stsien CE_DISPACT(a, 0, 0,		0, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
135*6dfee483Stsien CE_DISPACT(a, 0, 0,		1, 0) = CE_DISP_POSS_PERS | CE_ACT_LKYCHK; \
136*6dfee483Stsien CE_DISPACT(a, 0, 0,		1, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
137*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_M,	0, 0) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
138*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_M,	0, 1) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
139*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_M,	1, 0) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
140*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_M,	1, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
141*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_O,	0, 0) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
142*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_O,	0, 1) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
143*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_O,	1, 0) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
144*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_O,	1, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
145*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_E,	0, 0) = CE_DISP_INTERMITTENT | CE_ACT_DONE; \
146*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_E,	0, 1) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
147*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_E,	1, 0) = CE_DISP_POSS_PERS | CE_ACT_LKYCHK; \
148*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_E,	1, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
149*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_S,	0, 0) = CE_DISP_INTERMITTENT | CE_ACT_DONE; \
150*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_S,	0, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
151*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_S,	1, 0) = CE_DISP_POSS_PERS | CE_ACT_LKYCHK; \
152*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_S,	1, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
153*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_I,	0, 0) = CE_DISP_UNKNOWN | CE_ACT_DONE; \
154*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_I,	0, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
155*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_I,	1, 0) = CE_DISP_POSS_PERS | CE_ACT_LKYCHK; \
156*6dfee483Stsien CE_DISPACT(a, 1, EC_STATE_I,	1, 1) = CE_DISP_POSS_STICKY | CE_ACT_PTNRCHK; \
157*6dfee483Stsien }
158*6dfee483Stsien 
159*6dfee483Stsien #endif	/* !_ASM */
160*6dfee483Stsien 
161*6dfee483Stsien /*
162*6dfee483Stsien  * Legacy error type names corresponding to the flt_status bits
163*6dfee483Stsien  */
164*6dfee483Stsien #define	ERR_TYPE_DESC_INTERMITTENT	"Intermittent"
165*6dfee483Stsien #define	ERR_TYPE_DESC_PERSISTENT	"Persistent"
166*6dfee483Stsien #define	ERR_TYPE_DESC_STICKY		"Sticky"
167*6dfee483Stsien #define	ERR_TYPE_DESC_UNKNOWN		"Unknown"
168*6dfee483Stsien 
169*6dfee483Stsien /*
170*6dfee483Stsien  * flt_disp for a CE will record all scrub test data for the extended
171*6dfee483Stsien  * classification attempt.
172*6dfee483Stsien  *
173*6dfee483Stsien  * --------------------------------------------------------------------------
174*6dfee483Stsien  * |            | partner |   |          | leaky   | partner | detector     |
175*6dfee483Stsien  * | partner id | type    | - | skipcode | results | results | results      |
176*6dfee483Stsien  * |63	      32|31     30|   |27      24|23     16|15      8|7            0|
177*6dfee483Stsien  * --------------------------------------------------------------------------
178*6dfee483Stsien  */
179*6dfee483Stsien #define	CE_XDIAG_DTCRMASK		0xffULL
180*6dfee483Stsien #define	CE_XDIAG_PTNRSHIFT		8
181*6dfee483Stsien #define	CE_XDIAG_PTNRMASK		(0xffULL << CE_XDIAG_PTNRSHIFT)
182*6dfee483Stsien #define	CE_XDIAG_LKYSHIFT		16
183*6dfee483Stsien #define	CE_XDIAG_LKYMASK		(0xffULL << CE_XDIAG_LKYSHIFT)
184*6dfee483Stsien #define	CE_XDIAG_SKIPCODESHIFT		24
185*6dfee483Stsien #define	CE_XDIAG_SKIPCODEMASK		(0xfULL << CE_XDIAG_SKIPCODESHIFT)
186*6dfee483Stsien #define	CE_XDIAG_PTNRTYPESHIFT		30
187*6dfee483Stsien #define	CE_XDIAG_PTNRTYPEMASK		(0x3ULL << CE_XDIAG_PTNRTYPESHIFT)
188*6dfee483Stsien #define	CE_XDIAG_PTNRIDSHIFT		32
189*6dfee483Stsien 
190*6dfee483Stsien /*
191*6dfee483Stsien  * Given a CE flt_disp set the given field
192*6dfee483Stsien  */
193*6dfee483Stsien #define	CE_XDIAG_SETPTNRID(disp, id) \
194*6dfee483Stsien 	((disp) |= (uint64_t)(id) << CE_XDIAG_PTNRIDSHIFT)
195*6dfee483Stsien #define	CE_XDIAG_SETPTNRTYPE(disp, type) \
196*6dfee483Stsien 	((disp) |= (uint64_t)type << CE_XDIAG_PTNRTYPESHIFT)
197*6dfee483Stsien #define	CE_XDIAG_SETSKIPCODE(disp, code) \
198*6dfee483Stsien 	((disp) |= (uint64_t)code << CE_XDIAG_SKIPCODESHIFT)
199*6dfee483Stsien #define	CE_XDIAG_SETLKYINFO(disp, result) \
200*6dfee483Stsien 	((disp) |= (uint64_t)result << CE_XDIAG_LKYSHIFT)
201*6dfee483Stsien #define	CE_XDIAG_SETPTNRINFO(disp, result) \
202*6dfee483Stsien 	((disp) |= (uint64_t)result << CE_XDIAG_PTNRSHIFT)
203*6dfee483Stsien #define	CE_XDIAG_SETDTCRINFO(disp, result) \
204*6dfee483Stsien 	((disp) |= (uint64_t)result)
205*6dfee483Stsien 
206*6dfee483Stsien /*
207*6dfee483Stsien  * Given a CE flt_disp extract the requested component
208*6dfee483Stsien  */
209*6dfee483Stsien #define	CE_XDIAG_DTCRINFO(disp)	((disp) & CE_XDIAG_DTCRMASK)
210*6dfee483Stsien #define	CE_XDIAG_PTNRINFO(disp)	(((disp) & CE_XDIAG_PTNRMASK) >> \
211*6dfee483Stsien     CE_XDIAG_PTNRSHIFT)
212*6dfee483Stsien #define	CE_XDIAG_LKYINFO(disp)	(((disp) & CE_XDIAG_LKYMASK) >> \
213*6dfee483Stsien     CE_XDIAG_LKYSHIFT)
214*6dfee483Stsien #define	CE_XDIAG_SKIPCODE(disp)	(((disp) & CE_XDIAG_SKIPCODEMASK) >> \
215*6dfee483Stsien     CE_XDIAG_SKIPCODESHIFT)
216*6dfee483Stsien #define	CE_XDIAG_PTNRTYPE(disp)	(((disp) & CE_XDIAG_PTNRTYPEMASK) >> \
217*6dfee483Stsien     CE_XDIAG_PTNRTYPESHIFT)
218*6dfee483Stsien #define	CE_XDIAG_PTNRID(disp)	((disp) >> CE_XDIAG_PTNRIDSHIFT)
219*6dfee483Stsien 
220*6dfee483Stsien /*
221*6dfee483Stsien  * Format of individual detector/partner/leaky test results.  CE_XDIAG_EXTALG
222*6dfee483Stsien  * in the detector case indicates that the extended classification algorithm
223*6dfee483Stsien  * has been applied;  common code uses this to distinguish between old and new.
224*6dfee483Stsien  * In the partner check and leaky check cases CE_XDIAG_EXTALG is used to
225*6dfee483Stsien  * indicate that the given test has run and recorded its results in its
226*6dfee483Stsien  * result field.
227*6dfee483Stsien  */
228*6dfee483Stsien #define	CE_XDIAG_STATE_MASK	0x7	/* Low 3 bits are for MOESI state */
229*6dfee483Stsien #define	CE_XDIAG_AFARMATCH	0x08	/* Line at e$ index matched AFAR */
230*6dfee483Stsien #define	CE_XDIAG_NOLOGOUT	0x10	/* Logout data unavailable */
231*6dfee483Stsien #define	CE_XDIAG_CE1		0x20	/* CE logged on casx during scrub */
232*6dfee483Stsien #define	CE_XDIAG_CE2		0x40	/* CE logged on post-scrub reread */
233*6dfee483Stsien #define	CE_XDIAG_EXTALG		0x80	/* Extended algorithm applied */
234*6dfee483Stsien 
235*6dfee483Stsien /*
236*6dfee483Stsien  * Extract classification information for detector/partner.  Expects
237*6dfee483Stsien  * a value from one of CE_XDIAG_{DTCR,PTNR,LKY}_INFO.
238*6dfee483Stsien  */
239*6dfee483Stsien #define	CE_XDIAG_AFARMATCHED(c)		(((c) & CE_XDIAG_AFARMATCH) != 0)
240*6dfee483Stsien #define	CE_XDIAG_LOGOUTVALID(c)		(((c) & CE_XDIAG_NOLOGOUT) == 0)
241*6dfee483Stsien #define	CE_XDIAG_CE1SEEN(c)		(((c) & CE_XDIAG_CE1) != 0)
242*6dfee483Stsien #define	CE_XDIAG_CE2SEEN(c)		(((c) & CE_XDIAG_CE2) != 0)
243*6dfee483Stsien #define	CE_XDIAG_STATE(c)		(CE_XDIAG_AFARMATCHED(c) ? \
244*6dfee483Stsien 	((c) & CE_XDIAG_STATE_MASK) : 0)
245*6dfee483Stsien #define	CE_XDIAG_EXT_ALG_APPLIED(c)	(((c) & CE_XDIAG_EXTALG) != 0)
246*6dfee483Stsien 
247*6dfee483Stsien /*
248*6dfee483Stsien  * A leaky or partner test is considered valid if the line was not present
249*6dfee483Stsien  * in cache, or was present but Invalid, at the time of the additional scrub.
250*6dfee483Stsien  */
251*6dfee483Stsien #define	CE_XDIAG_TESTVALID(c) (CE_XDIAG_EXT_ALG_APPLIED(c) && \
252*6dfee483Stsien 	(!CE_XDIAG_AFARMATCHED(c) || CE_XDIAG_STATE(c) == EC_STATE_I))
253*6dfee483Stsien 
254*6dfee483Stsien /*
255*6dfee483Stsien  * Skipcodes - reasons for not applying extended diags; 4 bits
256*6dfee483Stsien  */
257*6dfee483Stsien #define	CE_XDIAG_SKIP_NOPP		0x1	/* Can't lookup page pointer */
258*6dfee483Stsien #define	CE_XDIAG_SKIP_PAGEDET		0x2	/* Page deteriorating/retired */
259*6dfee483Stsien #define	CE_XDIAG_SKIP_NOTMEM		0x3	/* AFAR is not memory */
260*6dfee483Stsien #define	CE_XDIAG_SKIP_DUPFAIL		0x4	/* errorq recirculate failed */
261*6dfee483Stsien #define	CE_XDIAG_SKIP_NOPTNR		0x5	/* no suitable partner avail */
262*6dfee483Stsien #define	CE_XDIAG_SKIP_UNIPROC		0x6	/* test needs 2 or more cpus */
263*6dfee483Stsien #define	CE_XDIAG_SKIP_ACTBAD		0x7	/* bad action lookup - bug */
264*6dfee483Stsien #define	CE_XDIAG_SKIP_NOSCRUB		0x8	/* detector did not scrub */
265*6dfee483Stsien 
266*6dfee483Stsien /*
267*6dfee483Stsien  * Partner type information.
268*6dfee483Stsien  */
269*6dfee483Stsien #define	CE_XDIAG_PTNR_REMOTE	0x0	/* partner in different lgroup */
270*6dfee483Stsien #define	CE_XDIAG_PTNR_LOCAL	0x1	/* partner in same lgroup */
271*6dfee483Stsien #define	CE_XDIAG_PTNR_SIBLING	0x2	/* partner is a sibling core */
272*6dfee483Stsien #define	CE_XDIAG_PTNR_SELF	0x3	/* partnered self */
273*6dfee483Stsien 
274*6dfee483Stsien #ifdef	__cplusplus
275*6dfee483Stsien }
276*6dfee483Stsien #endif
277*6dfee483Stsien 
278*6dfee483Stsien #endif	/* _SYS_ERRCLASSIFY_H */
279