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)
25 #include <asm/sibyte/sb1250_scd.h>
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
36 /* XXX should come from config1 XXX */
37 #define SB1_CACHE_INDEX_MASK 0x1fe0
39 #define CP0_ERRCTL_RECOVERABLE (1 << 31)
40 #define CP0_ERRCTL_DCACHE (1 << 30)
41 #define CP0_ERRCTL_ICACHE (1 << 29)
42 #define CP0_ERRCTL_MULTIBUS (1 << 23)
43 #define CP0_ERRCTL_MC_TLB (1 << 15)
44 #define CP0_ERRCTL_MC_TIMEOUT (1 << 14)
46 #define CP0_CERRI_TAG_PARITY (1 << 29)
47 #define CP0_CERRI_DATA_PARITY (1 << 28)
48 #define CP0_CERRI_EXTERNAL (1 << 26)
50 #define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL))
51 #define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY)
53 #define CP0_CERRD_MULTIPLE (1 << 31)
54 #define CP0_CERRD_TAG_STATE (1 << 30)
55 #define CP0_CERRD_TAG_ADDRESS (1 << 29)
56 #define CP0_CERRD_DATA_SBE (1 << 28)
57 #define CP0_CERRD_DATA_DBE (1 << 27)
58 #define CP0_CERRD_EXTERNAL (1 << 26)
59 #define CP0_CERRD_LOAD (1 << 25)
60 #define CP0_CERRD_STORE (1 << 24)
61 #define CP0_CERRD_FILLWB (1 << 23)
62 #define CP0_CERRD_COHERENCY (1 << 22)
63 #define CP0_CERRD_DUPTAG (1 << 21)
65 #define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL))
66 #define CP0_CERRD_IDX_VALID(c) \
67 (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0)
68 #define CP0_CERRD_CAUSES \
69 (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG)
70 #define CP0_CERRD_TYPES \
71 (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL)
72 #define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE)
74 static uint32_t extract_ic(unsigned short addr
, int data
);
75 static uint32_t extract_dc(unsigned short addr
, int data
);
77 static inline void breakout_errctl(unsigned int val
)
79 if (val
& CP0_ERRCTL_RECOVERABLE
)
80 printk(" recoverable");
81 if (val
& CP0_ERRCTL_DCACHE
)
83 if (val
& CP0_ERRCTL_ICACHE
)
85 if (val
& CP0_ERRCTL_MULTIBUS
)
86 printk(" multiple-buserr");
90 static inline void breakout_cerri(unsigned int val
)
92 if (val
& CP0_CERRI_TAG_PARITY
)
93 printk(" tag-parity");
94 if (val
& CP0_CERRI_DATA_PARITY
)
95 printk(" data-parity");
96 if (val
& CP0_CERRI_EXTERNAL
)
101 static inline void breakout_cerrd(unsigned int val
)
103 switch (val
& CP0_CERRD_CAUSES
) {
107 case CP0_CERRD_STORE
:
110 case CP0_CERRD_FILLWB
:
113 case CP0_CERRD_COHERENCY
:
114 printk(" coherency,");
116 case CP0_CERRD_DUPTAG
:
120 printk(" NO CAUSE,");
123 if (!(val
& CP0_CERRD_TYPES
))
126 if (val
& CP0_CERRD_MULTIPLE
)
127 printk(" multi-err");
128 if (val
& CP0_CERRD_TAG_STATE
)
129 printk(" tag-state");
130 if (val
& CP0_CERRD_TAG_ADDRESS
)
131 printk(" tag-address");
132 if (val
& CP0_CERRD_DATA_SBE
)
134 if (val
& CP0_CERRD_DATA_DBE
)
136 if (val
& CP0_CERRD_EXTERNAL
)
142 #ifndef CONFIG_SIBYTE_BUS_WATCHER
144 static void check_bus_watcher(void)
146 uint32_t status
, l2_err
, memio_err
;
147 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
151 /* Destructive read, clears register and interrupt */
152 status
= csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS
));
153 /* Bit 31 is always on, but there's no #define for that */
154 if (status
& ~(1UL << 31)) {
155 l2_err
= csr_in32(IOADDR(A_BUS_L2_ERRORS
));
156 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
157 l2_tag
= in64(IOADDR(A_L2_ECC_TAG
));
159 memio_err
= csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS
));
160 printk("Bus watcher error counters: %08x %08x\n", l2_err
, memio_err
);
161 printk("\nLast recorded signature:\n");
162 printk("Request %02x from %d, answered by %d with Dcode %d\n",
163 (unsigned int)(G_SCD_BERR_TID(status
) & 0x3f),
164 (int)(G_SCD_BERR_TID(status
) >> 6),
165 (int)G_SCD_BERR_RID(status
),
166 (int)G_SCD_BERR_DCODE(status
));
167 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
168 printk("Last L2 tag w/ bad ECC: %016llx\n", l2_tag
);
171 printk("Bus watcher indicates no error\n");
175 extern void check_bus_watcher(void);
178 asmlinkage
void sb1_cache_error(void)
180 uint32_t errctl
, cerr_i
, cerr_d
, dpalo
, dpahi
, eepc
, res
;
181 unsigned long long cerr_dpa
;
183 #ifdef CONFIG_SIBYTE_BW_TRACE
184 /* Freeze the trace buffer now */
185 csr_out32(M_SCD_TRACE_CFG_FREEZE
, IOADDR(A_SCD_TRACE_CFG
));
186 printk("Trace buffer frozen\n");
189 printk("Cache error exception on CPU %x:\n",
190 (read_c0_prid() >> 25) & 0x7);
192 __asm__
__volatile__ (
198 " mfc0 %2, $27, 1\n\t"
199 " dmfc0 $1, $27, 3\n\t"
200 " dsrl32 %3, $1, 0 \n\t"
201 " sll %4, $1, 0 \n\t"
204 : "=r" (errctl
), "=r" (cerr_i
), "=r" (cerr_d
),
205 "=r" (dpahi
), "=r" (dpalo
), "=r" (eepc
));
207 cerr_dpa
= (((uint64_t)dpahi
) << 32) | dpalo
;
208 printk(" c0_errorepc == %08x\n", eepc
);
209 printk(" c0_errctl == %08x", errctl
);
210 breakout_errctl(errctl
);
211 if (errctl
& CP0_ERRCTL_ICACHE
) {
212 printk(" c0_cerr_i == %08x", cerr_i
);
213 breakout_cerri(cerr_i
);
214 if (CP0_CERRI_IDX_VALID(cerr_i
)) {
215 /* Check index of EPC, allowing for delay slot */
216 if (((eepc
& SB1_CACHE_INDEX_MASK
) != (cerr_i
& SB1_CACHE_INDEX_MASK
)) &&
217 ((eepc
& SB1_CACHE_INDEX_MASK
) != ((cerr_i
& SB1_CACHE_INDEX_MASK
) - 4)))
218 printk(" cerr_i idx doesn't match eepc\n");
220 res
= extract_ic(cerr_i
& SB1_CACHE_INDEX_MASK
,
221 (cerr_i
& CP0_CERRI_DATA
) != 0);
223 printk("...didn't see indicated icache problem\n");
227 if (errctl
& CP0_ERRCTL_DCACHE
) {
228 printk(" c0_cerr_d == %08x", cerr_d
);
229 breakout_cerrd(cerr_d
);
230 if (CP0_CERRD_DPA_VALID(cerr_d
)) {
231 printk(" c0_cerr_dpa == %010llx\n", cerr_dpa
);
232 if (!CP0_CERRD_IDX_VALID(cerr_d
)) {
233 res
= extract_dc(cerr_dpa
& SB1_CACHE_INDEX_MASK
,
234 (cerr_d
& CP0_CERRD_DATA
) != 0);
236 printk("...didn't see indicated dcache problem\n");
238 if ((cerr_dpa
& SB1_CACHE_INDEX_MASK
) != (cerr_d
& SB1_CACHE_INDEX_MASK
))
239 printk(" cerr_d idx doesn't match cerr_dpa\n");
241 res
= extract_dc(cerr_d
& SB1_CACHE_INDEX_MASK
,
242 (cerr_d
& CP0_CERRD_DATA
) != 0);
244 printk("...didn't see indicated problem\n");
253 * Calling panic() when a fatal cache error occurs scrambles the
254 * state of the system (and the cache), making it difficult to
255 * investigate after the fact. However, if you just stall the CPU,
256 * the other CPU may keep on running, which is typically very
259 #ifdef CONFIG_SB1_CERR_STALL
263 panic("unhandled cache error");
268 /* Parity lookup table. */
269 static const uint8_t parity
[256] = {
270 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
271 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
272 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
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 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
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 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
279 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
280 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
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 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
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
288 /* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
289 static const uint64_t mask_72_64
[8] = {
290 0x0738C808099264FFULL
,
291 0x38C808099264FF07ULL
,
292 0xC808099264FF0738ULL
,
293 0x08099264FF0738C8ULL
,
294 0x099264FF0738C808ULL
,
295 0x9264FF0738C80809ULL
,
296 0x64FF0738C8080992ULL
,
297 0xFF0738C808099264ULL
300 /* Calculate the parity on a range of bits */
301 static char range_parity(uint64_t dword
, int max
, int min
)
306 for (i
=max
-min
; i
>=0; i
--) {
314 /* Calculate the 4-bit even byte-parity for an instruction */
315 static unsigned char inst_parity(uint32_t word
)
319 for (j
=0; j
<4; j
++) {
320 char byte_parity
= 0;
321 for (i
=0; i
<8; i
++) {
322 if (word
& 0x80000000)
323 byte_parity
= !byte_parity
;
327 parity
|= byte_parity
;
332 static uint32_t extract_ic(unsigned short addr
, int data
)
336 uint32_t taghi
, taglolo
, taglohi
;
337 unsigned long long taglo
, va
;
342 printk("Icache index 0x%04x ", addr
);
343 for (way
= 0; way
< 4; way
++) {
344 /* Index-load-tag-I */
345 __asm__
__volatile__ (
347 " .set noreorder \n\t"
350 " cache 4, 0(%3) \n\t"
352 " dmfc0 $1, $28 \n\t"
353 " dsrl32 %1, $1, 0 \n\t"
354 " sll %2, $1, 0 \n\t"
356 : "=r" (taghi
), "=r" (taglohi
), "=r" (taglolo
)
357 : "r" ((way
<< 13) | addr
));
359 taglo
= ((unsigned long long)taglohi
<< 32) | taglolo
;
361 lru
= (taghi
>> 14) & 0xff;
362 printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
363 ((addr
>> 5) & 0x3), /* bank */
364 ((addr
>> 7) & 0x3f), /* index */
370 va
= (taglo
& 0xC0000FFFFFFFE000ULL
) | addr
;
371 if ((taglo
& (1 << 31)) && (((taglo
>> 62) & 0x3) == 3))
372 va
|= 0x3FFFF00000000000ULL
;
373 valid
= ((taghi
>> 29) & 1);
375 tlo_tmp
= taglo
& 0xfff3ff;
376 if (((taglo
>> 10) & 1) ^ range_parity(tlo_tmp
, 23, 0)) {
377 printk(" ** bad parity in VTag0/G/ASID\n");
378 res
|= CP0_CERRI_TAG_PARITY
;
380 if (((taglo
>> 11) & 1) ^ range_parity(taglo
, 63, 24)) {
381 printk(" ** bad parity in R/VTag1\n");
382 res
|= CP0_CERRI_TAG_PARITY
;
385 if (valid
^ ((taghi
>> 27) & 1)) {
386 printk(" ** bad parity for valid bit\n");
387 res
|= CP0_CERRI_TAG_PARITY
;
389 printk(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n",
390 way
, va
, valid
, taghi
, taglo
);
393 uint32_t datahi
, insta
, instb
;
397 /* (hit all banks and ways) */
398 for (offset
= 0; offset
< 4; offset
++) {
399 /* Index-load-data-I */
400 __asm__
__volatile__ (
402 " .set noreorder\n\t"
405 " cache 6, 0(%3) \n\t"
406 " mfc0 %0, $29, 1\n\t"
407 " dmfc0 $1, $28, 1\n\t"
408 " dsrl32 %1, $1, 0 \n\t"
409 " sll %2, $1, 0 \n\t"
411 : "=r" (datahi
), "=r" (insta
), "=r" (instb
)
412 : "r" ((way
<< 13) | addr
| (offset
<< 3)));
413 predecode
= (datahi
>> 8) & 0xff;
414 if (((datahi
>> 16) & 1) != (uint32_t)range_parity(predecode
, 7, 0)) {
415 printk(" ** bad parity in predecode\n");
416 res
|= CP0_CERRI_DATA_PARITY
;
418 /* XXXKW should/could check predecode bits themselves */
419 if (((datahi
>> 4) & 0xf) ^ inst_parity(insta
)) {
420 printk(" ** bad parity in instruction a\n");
421 res
|= CP0_CERRI_DATA_PARITY
;
423 if ((datahi
& 0xf) ^ inst_parity(instb
)) {
424 printk(" ** bad parity in instruction b\n");
425 res
|= CP0_CERRI_DATA_PARITY
;
427 printk(" %05X-%08X%08X", datahi
, insta
, instb
);
435 /* Compute the ECC for a data doubleword */
436 static uint8_t dc_ecc(uint64_t dword
)
444 for (i
= 7; i
>= 0; i
--)
447 t
= dword
& mask_72_64
[i
];
448 w
= (uint32_t)(t
>> 32);
449 p
^= (parity
[w
>>24] ^ parity
[(w
>>16) & 0xFF]
450 ^ parity
[(w
>>8) & 0xFF] ^ parity
[w
& 0xFF]);
451 w
= (uint32_t)(t
& 0xFFFFFFFF);
452 p
^= (parity
[w
>>24] ^ parity
[(w
>>16) & 0xFF]
453 ^ parity
[(w
>>8) & 0xFF] ^ parity
[w
& 0xFF]);
463 static struct dc_state dc_states
[] = {
473 #define DC_TAG_VALID(state) \
474 (((state) == 0x0) || ((state) == 0xf) || ((state) == 0x13) || \
475 ((state) == 0x19) || ((state) == 0x16) || ((state) == 0x1c))
477 static char *dc_state_str(unsigned char state
)
479 struct dc_state
*dsc
= dc_states
;
480 while (dsc
->val
!= 0xff) {
481 if (dsc
->val
== state
)
488 static uint32_t extract_dc(unsigned short addr
, int data
)
492 uint32_t taghi
, taglolo
, taglohi
;
493 unsigned long long taglo
, pa
;
497 printk("Dcache index 0x%04x ", addr
);
498 for (way
= 0; way
< 4; way
++) {
499 __asm__
__volatile__ (
501 " .set noreorder\n\t"
504 " cache 5, 0(%3)\n\t" /* Index-load-tag-D */
505 " mfc0 %0, $29, 2\n\t"
506 " dmfc0 $1, $28, 2\n\t"
507 " dsrl32 %1, $1, 0\n\t"
510 : "=r" (taghi
), "=r" (taglohi
), "=r" (taglolo
)
511 : "r" ((way
<< 13) | addr
));
513 taglo
= ((unsigned long long)taglohi
<< 32) | taglolo
;
514 pa
= (taglo
& 0xFFFFFFE000ULL
) | addr
;
516 lru
= (taghi
>> 14) & 0xff;
517 printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
518 ((addr
>> 11) & 0x2) | ((addr
>> 5) & 1), /* bank */
519 ((addr
>> 6) & 0x3f), /* index */
525 state
= (taghi
>> 25) & 0x1f;
526 valid
= DC_TAG_VALID(state
);
527 printk(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n",
528 way
, pa
, dc_state_str(state
), state
, taghi
, taglo
);
530 if (((taglo
>> 11) & 1) ^ range_parity(taglo
, 39, 26)) {
531 printk(" ** bad parity in PTag1\n");
532 res
|= CP0_CERRD_TAG_ADDRESS
;
534 if (((taglo
>> 10) & 1) ^ range_parity(taglo
, 25, 13)) {
535 printk(" ** bad parity in PTag0\n");
536 res
|= CP0_CERRD_TAG_ADDRESS
;
539 res
|= CP0_CERRD_TAG_STATE
;
543 uint32_t datalohi
, datalolo
, datahi
;
544 unsigned long long datalo
;
548 for (offset
= 0; offset
< 4; offset
++) {
549 /* Index-load-data-D */
550 __asm__
__volatile__ (
552 " .set noreorder\n\t"
555 " cache 7, 0(%3)\n\t" /* Index-load-data-D */
556 " mfc0 %0, $29, 3\n\t"
557 " dmfc0 $1, $28, 3\n\t"
558 " dsrl32 %1, $1, 0 \n\t"
559 " sll %2, $1, 0 \n\t"
561 : "=r" (datahi
), "=r" (datalohi
), "=r" (datalolo
)
562 : "r" ((way
<< 13) | addr
| (offset
<< 3)));
563 datalo
= ((unsigned long long)datalohi
<< 32) | datalolo
;
564 ecc
= dc_ecc(datalo
);
567 bad_ecc
|= 1 << (3-offset
);
569 bits
= hweight8(ecc
);
570 res
|= (bits
== 1) ? CP0_CERRD_DATA_SBE
: CP0_CERRD_DATA_DBE
;
572 printk(" %02X-%016llX", datahi
, datalo
);
576 printk(" dwords w/ bad ECC: %d %d %d %d\n",
577 !!(bad_ecc
& 8), !!(bad_ecc
& 4),
578 !!(bad_ecc
& 2), !!(bad_ecc
& 1));