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