GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / mips / mm / cerr-sb1.c
blob197f65e01d6bf0fb39e20e49c3a17ffadb222ee3
1 /*
2 * Copyright (C) 2001,2002,2003 Broadcom Corporation
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 #include <linux/sched.h>
19 #include <asm/mipsregs.h>
20 #include <asm/sibyte/sb1250.h>
21 #include <asm/sibyte/sb1250_regs.h>
23 #if !defined(CONFIG_SIBYTE_BUS_WATCHER) || defined(CONFIG_SIBYTE_BW_TRACE)
24 #include <asm/io.h>
25 #include <asm/sibyte/sb1250_scd.h>
26 #endif
29 * We'd like to dump the L2_ECC_TAG register on errors, but errata make
30 * that unsafe... So for now we don't. (BCM1250/BCM112x erratum SOC-48.)
32 #undef DUMP_L2_ECC_TAG_ON_ERROR
34 /* SB1 definitions */
36 #define SB1_CACHE_INDEX_MASK 0x1fe0
38 #define CP0_ERRCTL_RECOVERABLE (1 << 31)
39 #define CP0_ERRCTL_DCACHE (1 << 30)
40 #define CP0_ERRCTL_ICACHE (1 << 29)
41 #define CP0_ERRCTL_MULTIBUS (1 << 23)
42 #define CP0_ERRCTL_MC_TLB (1 << 15)
43 #define CP0_ERRCTL_MC_TIMEOUT (1 << 14)
45 #define CP0_CERRI_TAG_PARITY (1 << 29)
46 #define CP0_CERRI_DATA_PARITY (1 << 28)
47 #define CP0_CERRI_EXTERNAL (1 << 26)
49 #define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL))
50 #define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY)
52 #define CP0_CERRD_MULTIPLE (1 << 31)
53 #define CP0_CERRD_TAG_STATE (1 << 30)
54 #define CP0_CERRD_TAG_ADDRESS (1 << 29)
55 #define CP0_CERRD_DATA_SBE (1 << 28)
56 #define CP0_CERRD_DATA_DBE (1 << 27)
57 #define CP0_CERRD_EXTERNAL (1 << 26)
58 #define CP0_CERRD_LOAD (1 << 25)
59 #define CP0_CERRD_STORE (1 << 24)
60 #define CP0_CERRD_FILLWB (1 << 23)
61 #define CP0_CERRD_COHERENCY (1 << 22)
62 #define CP0_CERRD_DUPTAG (1 << 21)
64 #define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL))
65 #define CP0_CERRD_IDX_VALID(c) \
66 (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0)
67 #define CP0_CERRD_CAUSES \
68 (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG)
69 #define CP0_CERRD_TYPES \
70 (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL)
71 #define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE)
73 static uint32_t extract_ic(unsigned short addr, int data);
74 static uint32_t extract_dc(unsigned short addr, int data);
76 static inline void breakout_errctl(unsigned int val)
78 if (val & CP0_ERRCTL_RECOVERABLE)
79 printk(" recoverable");
80 if (val & CP0_ERRCTL_DCACHE)
81 printk(" dcache");
82 if (val & CP0_ERRCTL_ICACHE)
83 printk(" icache");
84 if (val & CP0_ERRCTL_MULTIBUS)
85 printk(" multiple-buserr");
86 printk("\n");
89 static inline void breakout_cerri(unsigned int val)
91 if (val & CP0_CERRI_TAG_PARITY)
92 printk(" tag-parity");
93 if (val & CP0_CERRI_DATA_PARITY)
94 printk(" data-parity");
95 if (val & CP0_CERRI_EXTERNAL)
96 printk(" external");
97 printk("\n");
100 static inline void breakout_cerrd(unsigned int val)
102 switch (val & CP0_CERRD_CAUSES) {
103 case CP0_CERRD_LOAD:
104 printk(" load,");
105 break;
106 case CP0_CERRD_STORE:
107 printk(" store,");
108 break;
109 case CP0_CERRD_FILLWB:
110 printk(" fill/wb,");
111 break;
112 case CP0_CERRD_COHERENCY:
113 printk(" coherency,");
114 break;
115 case CP0_CERRD_DUPTAG:
116 printk(" duptags,");
117 break;
118 default:
119 printk(" NO CAUSE,");
120 break;
122 if (!(val & CP0_CERRD_TYPES))
123 printk(" NO TYPE");
124 else {
125 if (val & CP0_CERRD_MULTIPLE)
126 printk(" multi-err");
127 if (val & CP0_CERRD_TAG_STATE)
128 printk(" tag-state");
129 if (val & CP0_CERRD_TAG_ADDRESS)
130 printk(" tag-address");
131 if (val & CP0_CERRD_DATA_SBE)
132 printk(" data-SBE");
133 if (val & CP0_CERRD_DATA_DBE)
134 printk(" data-DBE");
135 if (val & CP0_CERRD_EXTERNAL)
136 printk(" external");
138 printk("\n");
141 #ifndef CONFIG_SIBYTE_BUS_WATCHER
143 static void check_bus_watcher(void)
145 uint32_t status, l2_err, memio_err;
146 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
147 uint64_t l2_tag;
148 #endif
150 /* Destructive read, clears register and interrupt */
151 status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
152 /* Bit 31 is always on, but there's no #define for that */
153 if (status & ~(1UL << 31)) {
154 l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
155 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
156 l2_tag = in64(IOADDR(A_L2_ECC_TAG));
157 #endif
158 memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
159 printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
160 printk("\nLast recorded signature:\n");
161 printk("Request %02x from %d, answered by %d with Dcode %d\n",
162 (unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
163 (int)(G_SCD_BERR_TID(status) >> 6),
164 (int)G_SCD_BERR_RID(status),
165 (int)G_SCD_BERR_DCODE(status));
166 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
167 printk("Last L2 tag w/ bad ECC: %016llx\n", l2_tag);
168 #endif
169 } else {
170 printk("Bus watcher indicates no error\n");
173 #else
174 extern void check_bus_watcher(void);
175 #endif
177 asmlinkage void sb1_cache_error(void)
179 uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
180 unsigned long long cerr_dpa;
182 #ifdef CONFIG_SIBYTE_BW_TRACE
183 /* Freeze the trace buffer now */
184 #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
185 csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
186 #else
187 csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
188 #endif
189 printk("Trace buffer frozen\n");
190 #endif
192 printk("Cache error exception on CPU %x:\n",
193 (read_c0_prid() >> 25) & 0x7);
195 __asm__ __volatile__ (
196 " .set push\n\t"
197 " .set mips64\n\t"
198 " .set noat\n\t"
199 " mfc0 %0, $26\n\t"
200 " mfc0 %1, $27\n\t"
201 " mfc0 %2, $27, 1\n\t"
202 " dmfc0 $1, $27, 3\n\t"
203 " dsrl32 %3, $1, 0 \n\t"
204 " sll %4, $1, 0 \n\t"
205 " mfc0 %5, $30\n\t"
206 " .set pop"
207 : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d),
208 "=r" (dpahi), "=r" (dpalo), "=r" (eepc));
210 cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo;
211 printk(" c0_errorepc == %08x\n", eepc);
212 printk(" c0_errctl == %08x", errctl);
213 breakout_errctl(errctl);
214 if (errctl & CP0_ERRCTL_ICACHE) {
215 printk(" c0_cerr_i == %08x", cerr_i);
216 breakout_cerri(cerr_i);
217 if (CP0_CERRI_IDX_VALID(cerr_i)) {
218 /* Check index of EPC, allowing for delay slot */
219 if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) &&
220 ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4)))
221 printk(" cerr_i idx doesn't match eepc\n");
222 else {
223 res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK,
224 (cerr_i & CP0_CERRI_DATA) != 0);
225 if (!(res & cerr_i))
226 printk("...didn't see indicated icache problem\n");
230 if (errctl & CP0_ERRCTL_DCACHE) {
231 printk(" c0_cerr_d == %08x", cerr_d);
232 breakout_cerrd(cerr_d);
233 if (CP0_CERRD_DPA_VALID(cerr_d)) {
234 printk(" c0_cerr_dpa == %010llx\n", cerr_dpa);
235 if (!CP0_CERRD_IDX_VALID(cerr_d)) {
236 res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK,
237 (cerr_d & CP0_CERRD_DATA) != 0);
238 if (!(res & cerr_d))
239 printk("...didn't see indicated dcache problem\n");
240 } else {
241 if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK))
242 printk(" cerr_d idx doesn't match cerr_dpa\n");
243 else {
244 res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK,
245 (cerr_d & CP0_CERRD_DATA) != 0);
246 if (!(res & cerr_d))
247 printk("...didn't see indicated problem\n");
253 check_bus_watcher();
256 * Calling panic() when a fatal cache error occurs scrambles the
257 * state of the system (and the cache), making it difficult to
258 * investigate after the fact. However, if you just stall the CPU,
259 * the other CPU may keep on running, which is typically very
260 * undesirable.
262 #ifdef CONFIG_SB1_CERR_STALL
263 while (1)
265 #else
266 panic("unhandled cache error");
267 #endif
271 /* Parity lookup table. */
272 static const uint8_t parity[256] = {
273 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
274 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
275 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
276 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
277 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
278 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
279 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
280 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
281 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
282 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
283 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
284 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
285 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
286 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
287 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
288 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
291 /* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
292 static const uint64_t mask_72_64[8] = {
293 0x0738C808099264FFULL,
294 0x38C808099264FF07ULL,
295 0xC808099264FF0738ULL,
296 0x08099264FF0738C8ULL,
297 0x099264FF0738C808ULL,
298 0x9264FF0738C80809ULL,
299 0x64FF0738C8080992ULL,
300 0xFF0738C808099264ULL
303 /* Calculate the parity on a range of bits */
304 static char range_parity(uint64_t dword, int max, int min)
306 char parity = 0;
307 int i;
308 dword >>= min;
309 for (i=max-min; i>=0; i--) {
310 if (dword & 0x1)
311 parity = !parity;
312 dword >>= 1;
314 return parity;
317 /* Calculate the 4-bit even byte-parity for an instruction */
318 static unsigned char inst_parity(uint32_t word)
320 int i, j;
321 char parity = 0;
322 for (j=0; j<4; j++) {
323 char byte_parity = 0;
324 for (i=0; i<8; i++) {
325 if (word & 0x80000000)
326 byte_parity = !byte_parity;
327 word <<= 1;
329 parity <<= 1;
330 parity |= byte_parity;
332 return parity;
335 static uint32_t extract_ic(unsigned short addr, int data)
337 unsigned short way;
338 int valid;
339 uint32_t taghi, taglolo, taglohi;
340 unsigned long long taglo, va;
341 uint64_t tlo_tmp;
342 uint8_t lru;
343 int res = 0;
345 printk("Icache index 0x%04x ", addr);
346 for (way = 0; way < 4; way++) {
347 /* Index-load-tag-I */
348 __asm__ __volatile__ (
349 " .set push \n\t"
350 " .set noreorder \n\t"
351 " .set mips64 \n\t"
352 " .set noat \n\t"
353 " cache 4, 0(%3) \n\t"
354 " mfc0 %0, $29 \n\t"
355 " dmfc0 $1, $28 \n\t"
356 " dsrl32 %1, $1, 0 \n\t"
357 " sll %2, $1, 0 \n\t"
358 " .set pop"
359 : "=r" (taghi), "=r" (taglohi), "=r" (taglolo)
360 : "r" ((way << 13) | addr));
362 taglo = ((unsigned long long)taglohi << 32) | taglolo;
363 if (way == 0) {
364 lru = (taghi >> 14) & 0xff;
365 printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
366 ((addr >> 5) & 0x3), /* bank */
367 ((addr >> 7) & 0x3f), /* index */
368 (lru & 0x3),
369 ((lru >> 2) & 0x3),
370 ((lru >> 4) & 0x3),
371 ((lru >> 6) & 0x3));
373 va = (taglo & 0xC0000FFFFFFFE000ULL) | addr;
374 if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
375 va |= 0x3FFFF00000000000ULL;
376 valid = ((taghi >> 29) & 1);
377 if (valid) {
378 tlo_tmp = taglo & 0xfff3ff;
379 if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {
380 printk(" ** bad parity in VTag0/G/ASID\n");
381 res |= CP0_CERRI_TAG_PARITY;
383 if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {
384 printk(" ** bad parity in R/VTag1\n");
385 res |= CP0_CERRI_TAG_PARITY;
388 if (valid ^ ((taghi >> 27) & 1)) {
389 printk(" ** bad parity for valid bit\n");
390 res |= CP0_CERRI_TAG_PARITY;
392 printk(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n",
393 way, va, valid, taghi, taglo);
395 if (data) {
396 uint32_t datahi, insta, instb;
397 uint8_t predecode;
398 int offset;
400 /* (hit all banks and ways) */
401 for (offset = 0; offset < 4; offset++) {
402 /* Index-load-data-I */
403 __asm__ __volatile__ (
404 " .set push\n\t"
405 " .set noreorder\n\t"
406 " .set mips64\n\t"
407 " .set noat\n\t"
408 " cache 6, 0(%3) \n\t"
409 " mfc0 %0, $29, 1\n\t"
410 " dmfc0 $1, $28, 1\n\t"
411 " dsrl32 %1, $1, 0 \n\t"
412 " sll %2, $1, 0 \n\t"
413 " .set pop \n"
414 : "=r" (datahi), "=r" (insta), "=r" (instb)
415 : "r" ((way << 13) | addr | (offset << 3)));
416 predecode = (datahi >> 8) & 0xff;
417 if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) {
418 printk(" ** bad parity in predecode\n");
419 res |= CP0_CERRI_DATA_PARITY;
421 /* XXXKW should/could check predecode bits themselves */
422 if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {
423 printk(" ** bad parity in instruction a\n");
424 res |= CP0_CERRI_DATA_PARITY;
426 if ((datahi & 0xf) ^ inst_parity(instb)) {
427 printk(" ** bad parity in instruction b\n");
428 res |= CP0_CERRI_DATA_PARITY;
430 printk(" %05X-%08X%08X", datahi, insta, instb);
432 printk("\n");
435 return res;
438 /* Compute the ECC for a data doubleword */
439 static uint8_t dc_ecc(uint64_t dword)
441 uint64_t t;
442 uint32_t w;
443 uint8_t p;
444 int i;
446 p = 0;
447 for (i = 7; i >= 0; i--)
449 p <<= 1;
450 t = dword & mask_72_64[i];
451 w = (uint32_t)(t >> 32);
452 p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
453 ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
454 w = (uint32_t)(t & 0xFFFFFFFF);
455 p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
456 ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
458 return p;
461 struct dc_state {
462 unsigned char val;
463 char *name;
466 static struct dc_state dc_states[] = {
467 { 0x00, "INVALID" },
468 { 0x0f, "COH-SHD" },
469 { 0x13, "NCO-E-C" },
470 { 0x19, "NCO-E-D" },
471 { 0x16, "COH-E-C" },
472 { 0x1c, "COH-E-D" },
473 { 0xff, "*ERROR*" }
476 #define DC_TAG_VALID(state) \
477 (((state) == 0x0) || ((state) == 0xf) || ((state) == 0x13) || \
478 ((state) == 0x19) || ((state) == 0x16) || ((state) == 0x1c))
480 static char *dc_state_str(unsigned char state)
482 struct dc_state *dsc = dc_states;
483 while (dsc->val != 0xff) {
484 if (dsc->val == state)
485 break;
486 dsc++;
488 return dsc->name;
491 static uint32_t extract_dc(unsigned short addr, int data)
493 int valid, way;
494 unsigned char state;
495 uint32_t taghi, taglolo, taglohi;
496 unsigned long long taglo, pa;
497 uint8_t ecc, lru;
498 int res = 0;
500 printk("Dcache index 0x%04x ", addr);
501 for (way = 0; way < 4; way++) {
502 __asm__ __volatile__ (
503 " .set push\n\t"
504 " .set noreorder\n\t"
505 " .set mips64\n\t"
506 " .set noat\n\t"
507 " cache 5, 0(%3)\n\t" /* Index-load-tag-D */
508 " mfc0 %0, $29, 2\n\t"
509 " dmfc0 $1, $28, 2\n\t"
510 " dsrl32 %1, $1, 0\n\t"
511 " sll %2, $1, 0\n\t"
512 " .set pop"
513 : "=r" (taghi), "=r" (taglohi), "=r" (taglolo)
514 : "r" ((way << 13) | addr));
516 taglo = ((unsigned long long)taglohi << 32) | taglolo;
517 pa = (taglo & 0xFFFFFFE000ULL) | addr;
518 if (way == 0) {
519 lru = (taghi >> 14) & 0xff;
520 printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
521 ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */
522 ((addr >> 6) & 0x3f), /* index */
523 (lru & 0x3),
524 ((lru >> 2) & 0x3),
525 ((lru >> 4) & 0x3),
526 ((lru >> 6) & 0x3));
528 state = (taghi >> 25) & 0x1f;
529 valid = DC_TAG_VALID(state);
530 printk(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n",
531 way, pa, dc_state_str(state), state, taghi, taglo);
532 if (valid) {
533 if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {
534 printk(" ** bad parity in PTag1\n");
535 res |= CP0_CERRD_TAG_ADDRESS;
537 if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {
538 printk(" ** bad parity in PTag0\n");
539 res |= CP0_CERRD_TAG_ADDRESS;
541 } else {
542 res |= CP0_CERRD_TAG_STATE;
545 if (data) {
546 uint32_t datalohi, datalolo, datahi;
547 unsigned long long datalo;
548 int offset;
549 char bad_ecc = 0;
551 for (offset = 0; offset < 4; offset++) {
552 /* Index-load-data-D */
553 __asm__ __volatile__ (
554 " .set push\n\t"
555 " .set noreorder\n\t"
556 " .set mips64\n\t"
557 " .set noat\n\t"
558 " cache 7, 0(%3)\n\t" /* Index-load-data-D */
559 " mfc0 %0, $29, 3\n\t"
560 " dmfc0 $1, $28, 3\n\t"
561 " dsrl32 %1, $1, 0 \n\t"
562 " sll %2, $1, 0 \n\t"
563 " .set pop"
564 : "=r" (datahi), "=r" (datalohi), "=r" (datalolo)
565 : "r" ((way << 13) | addr | (offset << 3)));
566 datalo = ((unsigned long long)datalohi << 32) | datalolo;
567 ecc = dc_ecc(datalo);
568 if (ecc != datahi) {
569 int bits;
570 bad_ecc |= 1 << (3-offset);
571 ecc ^= datahi;
572 bits = hweight8(ecc);
573 res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
575 printk(" %02X-%016llX", datahi, datalo);
577 printk("\n");
578 if (bad_ecc)
579 printk(" dwords w/ bad ECC: %d %d %d %d\n",
580 !!(bad_ecc & 8), !!(bad_ecc & 4),
581 !!(bad_ecc & 2), !!(bad_ecc & 1));
584 return res;