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