Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / bl / lib / ecc / src / BL_CKSyndrome.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: BL_CKSyndrome.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23/************************************************************************
24**
25** Copyright (C) 2007, Sun Microsystems, Inc.
26**
27** Sun considers its source code as an unpublished, proprietary
28** trade secret and it is available only under strict license provisions.
29** This copyright notice is placed here only to protect Sun in the event
30** the source is deemed a published work. Disassembly, decompilation,
31** or other means of reducing the object code to human readable form
32** is prohibited by the license agreement under which this code is
33** provided to the user or company in possession of this copy.
34**
35*************************************************************************/
36#ifndef __BL_CKSyndrome_h__
37#define __BL_CKSyndrome_h__
38
39#include "BL_CKEcc.h"
40#include "BL_Utils.h"
41
42// Syndrome class for BL Chip-kill ECC
43// Class provides basic routines to determine whether there is an
44// ECC error, whether it is single, double, or multiple bit, and, if
45// it is a single bit error, is it a data bit or check bit error.
46class BL_CKSyndrome
47{
48 public:
49 BL_CKSyndrome(BL_CKEccFile::ChipKillLine line, uint64_t savedECC) :
50 syndrome_(generateChipkillECC(line) ^ savedECC),
51 badDataNibblePosition_(0),
52 badCheckNibblePosition_(0),
53 dataCorrectionMask_(0),
54 checkCorrectionMask_(0)
55 {
56 if (syndrome_ > 0xffff)
57 {
58 fprintf(stderr,"BL_CKSyndrome::BL_CKSyndrome: bad syndrome");
59 exit(-1);
60 }
61 }
62
63
64 ~BL_CKSyndrome() {}
65
66 bool noError() const
67 {
68 return (syndrome_ == 0);
69 }
70
71 bool isUncorrectableError()
72 {
73 return !noError() &&
74 !isCorrectableDataBitError() &&
75 !isCorrectableCheckBitError();
76 }
77
78 // Implemented based on Table A-10 in N2 PRM rev1.1
79 bool isCorrectableDataBitError()
80 {
81 if (noError())
82 {
83 return false;
84 }
85
86 bool correctableDataBitError = false;
87 uint32_t s3 = bit_shift(syndrome_,0,4);
88 uint32_t s2 = bit_shift(syndrome_,4,4);
89 uint32_t s1 = bit_shift(syndrome_,8,4);
90 uint32_t s0 = bit_shift(syndrome_,12,4);
91 // If nibble s0 == 0 - Row 4 of Table A-10
92 if (s0 == 0)
93 {
94 // The remaining three nibble should be non zero
95 if ((s1 != 0) && (s2 != 0) && (s3 != 0))
96 {
97 // And equal
98 if ((s1 == s2) && (s1 == s3))
99 {
100 // For it to be a valid single-bit correctable
101 // data error
102 correctableDataBitError = true;
103 badDataNibblePosition_ = 30;
104 // Mask to be XOR'ed with Nibble 30 to fix data
105 dataCorrectionMask_ = s1;
106 }
107 }
108 }
109 // If nibble s1 == 0 - Case ab0c - Row 3 of Table A-10
110 else if (s1 == 0)
111 {
112 // The remaining three nibble should be non zero
113 if ((s0 != 0) && (s2 != 0) && (s3 != 0))
114 {
115 // And the value of syndrome nibble 3 should be
116 // the same as the value in the matrix of synd0
117 // and synd2
118 if (ab0cErrorValidationMatrix[s2][s0] == s3)
119 {
120 // For it to be a valid single-bit correctable
121 // data error
122 correctableDataBitError = true;
123 // Table A-13
124 badDataNibblePosition_ =
125 ab0cErrorNibbleIdentityMatrix[s2][s0];
126 // Mask to be XOR'ed with the nibble indexed
127 // by badDataNibblePosition_ to fix data
128 dataCorrectionMask_ = s2;
129 }
130 }
131 }
132 // If nibble s2 == 0 - Case a0bc - Row 2 of Table A-10
133 else if (s2 == 0)
134 {
135 // The remaining three nibble should be non zero
136 if ((s0 != 0) && (s1 != 0) && (s3 != 0))
137 {
138 // And the value of syndrome nibble 3 should be
139 // the same as the value in the matrix of synd0
140 // and synd1
141 if (a0bcErrorValidationMatrix[s1][s0] == s3)
142 {
143 // For it to be a valid single-bit correctable
144 // data error
145 correctableDataBitError = true;
146 // Table A-11
147 badDataNibblePosition_ =
148 a0bcErrorNibbleIdentityMatrix[s1][s0];
149 // Mask to be XOR'ed with nibble in
150 // badDataNibblePosition_ above to fix data
151 dataCorrectionMask_ = s1;
152 }
153 }
154 }
155 // If nibble s3 == 0 - Row 5 of Table A-10
156 else if (s3 == 0)
157 {
158 // The remaining three nibble should be non zero
159 if ((s0 != 0) && (s1 != 0) && (s2 != 0))
160 {
161 // And equal
162 if ((s0 == s1) && (s0 == s2))
163 {
164 // For it to be a valid single-bit correctable
165 // data error
166 correctableDataBitError = true;
167 badDataNibblePosition_ = 31;
168 // Mask to be XOR'ed with Nibble 31 to fix data
169 dataCorrectionMask_ = s0;
170 }
171 }
172 }
173 return correctableDataBitError;
174 }
175
176 // Implemented based on Table A-10 in N2 PRM rev1.1
177 bool isCorrectableCheckBitError()
178 {
179 if (noError())
180 {
181 return false;
182 }
183
184 bool correctableCheckBitError = false;
185 uint32_t s3 = bit_shift(syndrome_,0,4);
186 uint32_t s2 = bit_shift(syndrome_,4,4);
187 uint32_t s1 = bit_shift(syndrome_,8,4);
188 uint32_t s0 = bit_shift(syndrome_,12,4);
189 // If nibble s0 != 0 - Row 6 of Table A-10
190 if (s0 != 0)
191 {
192 // The remaining three nibble should be zero
193 if ((s1 == 0) && (s2 == 0) && (s3 == 0))
194 {
195 // For it to be a valid single-bit correctable
196 // check bit error
197 correctableCheckBitError = true;
198 // use big endian to index nibble position
199 badCheckNibblePosition_ = 3;
200 // This mask has to be XOR'ed with check nibble
201 // identified above to restore valid ECC
202 checkCorrectionMask_ = s0;
203 }
204 }
205 // If nibble s1 != 0 - Row 7 of Table A-10
206 else if (s1 != 0)
207 {
208 // The remaining three nibble should be zero
209 if ((s0 == 0) && (s2 == 0) && (s3 == 0))
210 {
211 // For it to be a valid single-bit correctable
212 // check bit error
213 correctableCheckBitError = true;
214 // use big endian to index nibble position
215 badCheckNibblePosition_ = 2;
216 checkCorrectionMask_ = s1;
217 // This mask has to be XOR'ed with check nibble
218 // identified above to restore valid ECC
219 }
220 }
221 // If nibble s2 != 0 - Row 8 of Table A-10
222 else if (s2 != 0)
223 {
224 // The remaining three nibble should be zero
225 if ((s0 == 0) && (s1 == 0) && (s3 == 0))
226 {
227 // For it to be a valid single-bit correctable
228 // check bit error
229 correctableCheckBitError = true;
230 // use big endian to index nibble position
231 badCheckNibblePosition_ = 1;
232 // This mask has to be XOR'ed with check nibble
233 // identified above to restore valid ECC
234 checkCorrectionMask_ = s2;
235 }
236 }
237 // If nibble s3 != 0 - Row 9 of Table A-10
238 else if (s3 != 0)
239 {
240 // The remaining three nibble should be zero
241 if ((s0 == 0) && (s1 == 0) && (s2 == 0))
242 {
243 // For it to be a valid single-bit correctable
244 // check bit error
245 correctableCheckBitError = true;
246 // use big endian to index nibble position
247 badCheckNibblePosition_ = 0;
248 // This mask has to be XOR'ed with check nibble
249 // identified above to restore valid ECC
250 checkCorrectionMask_ = s3;
251 }
252 }
253 return correctableCheckBitError;
254 }
255
256 uint64_t getSyndrome() const { return syndrome_; }
257
258 uint32_t getBadDataNibblePosition()
259 {
260 if (!isCorrectableDataBitError())
261 {
262 fprintf(stderr,"BL_CKSyndrome::"
263 "getBadDataNibblePosition(): "
264 "not correctable data error");
265 exit(-1);
266 }
267 return badDataNibblePosition_;
268 }
269
270 uint32_t getBadCheckNibblePosition()
271 {
272 if (!isCorrectableCheckBitError())
273 {
274 fprintf(stderr,"BL_CKSyndrome::"
275 "getBadCheckNibblePosition(): "
276 "not correctable check error");
277 exit(-1);
278 }
279 return badCheckNibblePosition_;
280 }
281
282 uint64_t getDataCorrectionMask()
283 {
284 if (!isCorrectableDataBitError())
285 {
286 fprintf(stderr,"BL_CKSyndrome::"
287 "getDataCorrectionMask(): "
288 "not correctable data error");
289 exit(-1);
290 }
291 return dataCorrectionMask_;
292 }
293
294 uint64_t getCheckCorrectionMask()
295 {
296 if (!isCorrectableCheckBitError())
297 {
298 fprintf(stderr,"BL_CKSyndrome::"
299 "getCheckCorrectionMask(): "
300 "not correctable check error");
301 exit(-1);
302 }
303 return checkCorrectionMask_;
304 }
305
306 bool correctChipKillLine(BL_CKEccFile::ChipKillLine &line)
307 {
308 if (!isCorrectableDataBitError())
309 {
310 return false;
311 }
312 uint32_t nibbleNdx = getBadDataNibblePosition();
313 uint64_t nibbleMask = getDataCorrectionMask();
314
315 if (nibbleNdx < 16)
316 {
317 line.lsdw ^= nibbleMask << (4 * nibbleNdx);
318 }
319 else
320 {
321 line.msdw ^= nibbleMask << (4 * (nibbleNdx - 16));
322 }
323 return true;
324 }
325
326 bool correctChipKillECC(uint64_t &ecc)
327 {
328 if (!isCorrectableCheckBitError())
329 {
330 return false;
331 }
332 uint32_t nibbleNdx = getBadCheckNibblePosition();
333 uint64_t nibbleMask = getCheckCorrectionMask();
334
335 ecc ^= nibbleMask << (4 * nibbleNdx);
336 return true;
337 }
338
339 protected:
340 BL_CKSyndrome();
341 uint64_t syndrome_;
342 uint32_t badDataNibblePosition_;
343 uint32_t badCheckNibblePosition_;
344 uint64_t dataCorrectionMask_;
345 uint64_t checkCorrectionMask_;
346
347 private:
348 // The following 2 Dimensional Matrix implements Table A-12 of
349 // N2 PRM rev1.1 First dimension is Syndrome0. Second
350 // dimension is Syndrome1 The values contained in the matrix
351 // are the possible values for Syndrome3 in hexadecimal for a
352 // given [synd0,synd1], the value of synd3 should exactly
353 // match the value present in this table for the data bit
354 // error to be correctable (single bit) otherwise it is an
355 // uncorrectable (multibit) error
356 static const uint32_t a0bcErrorValidationMatrix[16][16];
357
358 // The following 2 Dimensional Matrix implements Table A-11 of
359 // N2 PRM rev1.1 First dimension is Syndrome0. Second
360 // dimension is Syndrome1 // The data present at the
361 // intersection [synd0,synd1], represents the Data Nibble that
362 // has the correctable error! // The correction mask is the
363 // value of Syndrome1
364 static const uint32_t a0bcErrorNibbleIdentityMatrix[16][16];
365
366 // The following 2 Dimensional Matrix implements Table A-14 of
367 // N2 PRM rev1.1 First dimension is Syndrome0. Second
368 // dimension is Syndrome2 The values contained in the matrix
369 // are the possible values for Syndrome3 in hexadecimal for a
370 // given [synd0,synd2], the value of synd3 should exactly
371 // match the value present in this table for the data bit
372 // error to be correctable (single bit) otherwise it is an
373 // uncorrectable (multibit) error
374 static const uint32_t ab0cErrorValidationMatrix[16][16];
375
376 // The following 2 Dimensional Matrix implements Table A-13 of
377 // N2 PRM rev1.1 First dimension is Syndrome0. Second
378 // dimension is Syndrome2 // The data present at the
379 // intersection [synd0,synd2], represents the Data Nibble that
380 // has the correctable error!
381 // The correction mask is the value of Syndrome2
382 static const uint32_t ab0cErrorNibbleIdentityMatrix[16][16];
383};
384#endif //__BL_CKSyndrome_h__