Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: BL_Hsiao_30_7_Synd.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) 2006, 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_Hsiao_30_7_Synd_h__ | |
37 | #define __BL_Hsiao_30_7_Synd_h__ | |
38 | #include "BL_Utils.h" | |
39 | #include "BL_BaseSynd.h" | |
40 | #include "BL_HsiaoEcc.h" | |
41 | ||
42 | class BL_Hsiao_30_7_Synd : public BL_BaseSynd | |
43 | { | |
44 | public: | |
45 | ||
46 | BL_Hsiao_30_7_Synd(uint32_t syndrome) : BL_BaseSynd(syndrome) | |
47 | { | |
48 | if (syndrome > 0x7f) | |
49 | { | |
50 | fprintf(stderr,"ERROR: Bad Syndrome: 0x%x", syndrome); | |
51 | exit(-1); | |
52 | } | |
53 | } | |
54 | ||
55 | BL_Hsiao_30_7_Synd(uint32_t data, BL_EccBits ecc) : | |
56 | BL_BaseSynd(BL_Hsiao_30_7_Synd::calc_check_bits(data).get() ^ ecc.get()) | |
57 | {} | |
58 | ||
59 | ||
60 | ~BL_Hsiao_30_7_Synd() {} | |
61 | ||
62 | bool isDoubleBitError() const | |
63 | { | |
64 | return (syndrome_ != 0) && !isSingleBitError(); | |
65 | } | |
66 | ||
67 | bool isSingleBitError() const | |
68 | { | |
69 | if (syndrome_ == 0) | |
70 | return false; | |
71 | switch (nr_bits_set()) | |
72 | { | |
73 | case 1: | |
74 | case 3: | |
75 | return true; | |
76 | default: | |
77 | return false; | |
78 | } | |
79 | } | |
80 | ||
81 | bool isDataBitError() const | |
82 | { | |
83 | return (isSingleBitError() && !(is_power_of_two(syndrome_))); | |
84 | } | |
85 | ||
86 | // This method works because the check bits are at powers of 2 | |
87 | // (after substracting 0x80) so the data bits break up into | |
88 | // large ranges. | |
89 | uint32_t getDataBit() const | |
90 | { | |
91 | if (!isDataBitError()) | |
92 | { | |
93 | fprintf(stderr,"ERROR: Not data bit error!"); | |
94 | exit(-1); | |
95 | } | |
96 | ||
97 | return find_syndrome_ndx(); | |
98 | } | |
99 | ||
100 | bool isCheckBitError() const | |
101 | { | |
102 | return (isSingleBitError() && is_power_of_two(syndrome_)); | |
103 | } | |
104 | ||
105 | uint32_t getCheckBit() const | |
106 | { | |
107 | if (!isCheckBitError()) | |
108 | { | |
109 | fprintf(stderr,"ERROR: Not check bit error!"); | |
110 | exit(-1); | |
111 | } | |
112 | return bit2idx(syndrome_); | |
113 | } | |
114 | ||
115 | bool isMultipleBitError() const { return false; } | |
116 | ||
117 | static BL_EccBits calc_check_bits(uint32_t data) | |
118 | { | |
119 | uint32_t* patterns = BL_Hsiao_30_7_Synd::hsiao_30_7_patterns.patterns; | |
120 | return calc_checks(7, patterns, data); | |
121 | ||
122 | } | |
123 | ||
124 | #define BL_HSIAO_30_7_DIE(S) { \ | |
125 | fprintf(stderr, S " line: %d\n", __LINE__); \ | |
126 | exit(-1); \ | |
127 | } | |
128 | ||
129 | static void validate() | |
130 | { | |
131 | uint32_t data = 0x12345678; | |
132 | uint32_t ecc = BL_Hsiao_30_7_Synd::calc_check_bits(data).get(); | |
133 | ||
134 | BL_Hsiao_30_7_Synd syndrome = BL_Hsiao_30_7_Synd(data, ecc); | |
135 | ||
136 | if (!syndrome.noError()) | |
137 | BL_HSIAO_30_7_DIE("NoError fails"); | |
138 | ||
139 | int i; | |
140 | for (i = 0; i < 30; ++i) { | |
141 | syndrome = BL_Hsiao_30_7_Synd((1<<i)^data, ecc); | |
142 | ||
143 | if (syndrome.noError()) | |
144 | BL_HSIAO_30_7_DIE("NoError succeeds"); | |
145 | ||
146 | if (!syndrome.isSingleBitError()) | |
147 | BL_HSIAO_30_7_DIE("isSingleBit fails"); | |
148 | ||
149 | if (syndrome.isDoubleBitError()) | |
150 | BL_HSIAO_30_7_DIE("isDoubleBit succeeds"); | |
151 | ||
152 | if (syndrome.isMultipleBitError() || syndrome.isUncorrectableError()) | |
153 | BL_HSIAO_30_7_DIE("isMultipleBit/isUncorrectable succeeds"); | |
154 | ||
155 | if (syndrome.getDataBit() != i) | |
156 | BL_HSIAO_30_7_DIE("getDataBit mismatch"); | |
157 | } | |
158 | ||
159 | for (i = 0; i < 7; ++i) { | |
160 | syndrome = BL_Hsiao_30_7_Synd(data, (1<<i)^ecc); | |
161 | ||
162 | if (syndrome.noError()) | |
163 | BL_HSIAO_30_7_DIE("NoError succeeds"); | |
164 | ||
165 | if (!syndrome.isSingleBitError()) | |
166 | BL_HSIAO_30_7_DIE("isSingleBit fails"); | |
167 | ||
168 | if (syndrome.isDoubleBitError()) | |
169 | BL_HSIAO_30_7_DIE("isDoubleBit succeeds"); | |
170 | ||
171 | if (syndrome.isMultipleBitError() || syndrome.isUncorrectableError()) | |
172 | BL_HSIAO_30_7_DIE("isMultipleBit/isUncorrectable succeeds"); | |
173 | ||
174 | if (syndrome.getCheckBit() != i) | |
175 | BL_HSIAO_30_7_DIE("getCheckBit mismatch"); | |
176 | } | |
177 | ||
178 | for (i = 1; i < 30; ++i) { | |
179 | int j; | |
180 | for (j = 0; j < i; ++j) { | |
181 | syndrome = BL_Hsiao_30_7_Synd((1<<i)^(1<<j)^data, ecc); | |
182 | ||
183 | if (syndrome.noError()) | |
184 | BL_HSIAO_30_7_DIE("NoError succeeds"); | |
185 | ||
186 | if (syndrome.isSingleBitError()) | |
187 | BL_HSIAO_30_7_DIE("isSingleBit succeeds"); | |
188 | ||
189 | if (!syndrome.isDoubleBitError()) | |
190 | BL_HSIAO_30_7_DIE("isDoubleBit fails"); | |
191 | ||
192 | if (syndrome.isMultipleBitError()) | |
193 | BL_HSIAO_30_7_DIE("isMultipleBit succeeds"); | |
194 | ||
195 | if (!syndrome.isUncorrectableError()) | |
196 | BL_HSIAO_30_7_DIE("isUncorrectable fails"); | |
197 | } | |
198 | } | |
199 | ||
200 | for (i = 1; i < 7; ++i) { | |
201 | int j; | |
202 | for (j = 0; j < i; ++j) { | |
203 | ||
204 | syndrome = BL_Hsiao_30_7_Synd(data, (1<<i)^(1<<j)^ecc); | |
205 | ||
206 | if (syndrome.noError()) | |
207 | BL_HSIAO_30_7_DIE("NoError succeeds"); | |
208 | ||
209 | if (syndrome.isSingleBitError()) | |
210 | BL_HSIAO_30_7_DIE("isSingleBit succeeds"); | |
211 | ||
212 | if (!syndrome.isDoubleBitError()) | |
213 | BL_HSIAO_30_7_DIE("isDoubleBit fails"); | |
214 | ||
215 | if (syndrome.isMultipleBitError()) | |
216 | BL_HSIAO_30_7_DIE("isMultipleBit succeeds"); | |
217 | ||
218 | if (!syndrome.isUncorrectableError()) | |
219 | BL_HSIAO_30_7_DIE("isUncorrectable fails"); | |
220 | } | |
221 | } | |
222 | } | |
223 | ||
224 | #undef BL_HSIAO_30_7_DIE | |
225 | ||
226 | private: | |
227 | ||
228 | BL_Hsiao_30_7_Synd(); | |
229 | ||
230 | // Number of bits set in syndrome | |
231 | // This trick works up to 12 bits | |
232 | uint_t nr_bits_set() const | |
233 | { | |
234 | return (syndrome_ * 0x1001001001001ULL & 0x84210842108421ULL) % 0x1f; | |
235 | } | |
236 | ||
237 | int find_syndrome_ndx() const | |
238 | { | |
239 | switch (nr_bits_set()) | |
240 | { | |
241 | case 3: | |
242 | for (uint_t ndx = 0; ndx < 30; ++ndx) | |
243 | if (syndrome_ == hsiao_30_7_patterns.get(ndx).get()) | |
244 | return ndx; | |
245 | assert(0); | |
246 | break; | |
247 | default: | |
248 | break; | |
249 | } | |
250 | return -1; // -1 is didn't find it | |
251 | } | |
252 | ||
253 | class Patterns | |
254 | { | |
255 | public: | |
256 | uint_t patterns[7]; | |
257 | ||
258 | Patterns(); | |
259 | ||
260 | ~Patterns() {} | |
261 | ||
262 | BL_EccBits get(uint_t ndx) const { return syndromes[ndx]; } | |
263 | ||
264 | private: | |
265 | ||
266 | static uint64_t calc_pattern(uint_t pattern_ndx); | |
267 | ||
268 | static BL_EccBits syndromes[30]; | |
269 | }; | |
270 | ||
271 | static Patterns hsiao_30_7_patterns; | |
272 | ||
273 | }; | |
274 | ||
275 | #endif |