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