18 #include <linux/sched.h>
23 #if !defined(CONFIG_SIBYTE_BUS_WATCHER) || defined(CONFIG_SIBYTE_BW_TRACE)
32 #undef DUMP_L2_ECC_TAG_ON_ERROR
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)
77 static inline void breakout_errctl(
unsigned int val)
86 printk(
" multiple-buserr");
90 static inline void breakout_cerri(
unsigned int val)
101 static inline void breakout_cerrd(
unsigned int val)
142 #ifndef CONFIG_SIBYTE_BUS_WATCHER
147 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
154 if (status & ~(1
UL << 31)) {
156 #ifdef DUMP_L2_ECC_TAG_ON_ERROR
157 l2_tag = in64(
IOADDR(A_L2_ECC_TAG));
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",
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");
180 uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc,
res;
181 unsigned long long cerr_dpa;
183 #ifdef CONFIG_SIBYTE_BW_TRACE
185 #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
190 printk(
"Trace buffer frozen\n");
193 printk(
"Cache error exception on CPU %x:\n",
202 " mfc0 %2, $27, 1\n\t"
203 " dmfc0 $1, $27, 3\n\t"
204 " dsrl32 %3, $1, 0 \n\t"
205 " sll %4, $1, 0 \n\t"
208 :
"=r" (errctl),
"=r" (cerr_i),
"=r" (cerr_d),
209 "=r" (dpahi),
"=r" (dpalo),
"=r" (eepc));
211 cerr_dpa = (((
uint64_t)dpahi) << 32) | dpalo;
212 printk(
" c0_errorepc == %08x\n", eepc);
213 printk(
" c0_errctl == %08x", errctl);
214 breakout_errctl(errctl);
215 if (errctl & CP0_ERRCTL_ICACHE) {
216 printk(
" c0_cerr_i == %08x", cerr_i);
217 breakout_cerri(cerr_i);
221 ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4)))
222 printk(
" cerr_i idx doesn't match eepc\n");
224 res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK,
227 printk(
"...didn't see indicated icache problem\n");
231 if (errctl & CP0_ERRCTL_DCACHE) {
232 printk(
" c0_cerr_d == %08x", cerr_d);
233 breakout_cerrd(cerr_d);
235 printk(
" c0_cerr_dpa == %010llx\n", cerr_dpa);
240 printk(
"...didn't see indicated dcache problem\n");
243 printk(
" cerr_d idx doesn't match cerr_dpa\n");
245 res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK,
248 printk(
"...didn't see indicated problem\n");
263 #ifdef CONFIG_SB1_CERR_STALL
267 panic(
"unhandled cache error");
273 static const uint8_t parity[256] = {
274 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
275 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
276 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
277 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
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 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
283 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
284 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
285 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
286 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
287 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
288 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
289 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
293 static const uint64_t mask_72_64[8] = {
294 0x0738C808099264FFULL,
295 0x38C808099264FF07ULL,
296 0xC808099264FF0738ULL,
297 0x08099264FF0738C8ULL,
298 0x099264FF0738C808ULL,
299 0x9264FF0738C80809ULL,
300 0x64FF0738C8080992ULL,
301 0xFF0738C808099264ULL
310 for (i=max-min; i>=0; i--) {
323 for (j=0; j<4; j++) {
324 char byte_parity = 0;
325 for (i=0; i<8; i++) {
326 if (word & 0x80000000)
327 byte_parity = !byte_parity;
331 parity |= byte_parity;
341 unsigned long long taglo,
va;
346 printk(
"Icache index 0x%04x ", addr);
347 for (way = 0; way < 4; way++) {
351 " .set noreorder \n\t"
354 " cache 4, 0(%3) \n\t"
356 " dmfc0 $1, $28 \n\t"
357 " dsrl32 %1, $1, 0 \n\t"
358 " sll %2, $1, 0 \n\t"
360 :
"=r" (taghi),
"=r" (taglohi),
"=r" (taglolo)
361 :
"r" ((way << 13) | addr));
363 taglo = ((
unsigned long long)taglohi << 32) | taglolo;
365 lru = (taghi >> 14) & 0xff;
366 printk(
"[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
368 ((addr >> 7) & 0x3f),
374 va = (taglo & 0xC0000FFFFFFFE000ULL) | addr;
375 if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
376 va |= 0x3FFFF00000000000ULL;
377 valid = ((taghi >> 29) & 1);
379 tlo_tmp = taglo & 0xfff3ff;
380 if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {
381 printk(
" ** bad parity in VTag0/G/ASID\n");
384 if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {
385 printk(
" ** bad parity in R/VTag1\n");
389 if (valid ^ ((taghi >> 27) & 1)) {
390 printk(
" ** bad parity for valid bit\n");
393 printk(
" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n",
394 way, va, valid, taghi, taglo);
402 for (offset = 0; offset < 4; offset++) {
406 " .set noreorder\n\t"
409 " cache 6, 0(%3) \n\t"
410 " mfc0 %0, $29, 1\n\t"
411 " dmfc0 $1, $28, 1\n\t"
412 " dsrl32 %1, $1, 0 \n\t"
413 " sll %2, $1, 0 \n\t"
415 :
"=r" (datahi),
"=r" (insta),
"=r" (instb)
416 :
"r" ((way << 13) | addr | (offset << 3)));
417 predecode = (datahi >> 8) & 0xff;
418 if (((datahi >> 16) & 1) != (
uint32_t)range_parity(predecode, 7, 0)) {
419 printk(
" ** bad parity in predecode\n");
423 if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {
424 printk(
" ** bad parity in instruction a\n");
427 if ((datahi & 0xf) ^ inst_parity(instb)) {
428 printk(
" ** bad parity in instruction b\n");
431 printk(
" %05X-%08X%08X", datahi, insta, instb);
448 for (i = 7; i >= 0; i--)
451 t = dword & mask_72_64[
i];
453 p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
454 ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
456 p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
457 ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
467 static struct dc_state dc_states[] = {
477 #define DC_TAG_VALID(state) \
478 (((state) == 0x0) || ((state) == 0xf) || ((state) == 0x13) || \
479 ((state) == 0x19) || ((state) == 0x16) || ((state) == 0x1c))
481 static char *dc_state_str(
unsigned char state)
484 while (dsc->
val != 0xff) {
485 if (dsc->
val == state)
492 static uint32_t extract_dc(
unsigned short addr,
int data)
497 unsigned long long taglo, pa;
501 printk(
"Dcache index 0x%04x ", addr);
502 for (way = 0; way < 4; way++) {
505 " .set noreorder\n\t"
508 " cache 5, 0(%3)\n\t"
509 " mfc0 %0, $29, 2\n\t"
510 " dmfc0 $1, $28, 2\n\t"
511 " dsrl32 %1, $1, 0\n\t"
514 :
"=r" (taghi),
"=r" (taglohi),
"=r" (taglolo)
515 :
"r" ((way << 13) | addr));
517 taglo = ((
unsigned long long)taglohi << 32) | taglolo;
518 pa = (taglo & 0xFFFFFFE000ULL) | addr;
520 lru = (taghi >> 14) & 0xff;
521 printk(
"[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
522 ((addr >> 11) & 0x2) | ((addr >> 5) & 1),
523 ((addr >> 6) & 0x3f),
529 state = (taghi >> 25) & 0x1f;
531 printk(
" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n",
532 way, pa, dc_state_str(state), state, taghi, taglo);
534 if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {
535 printk(
" ** bad parity in PTag1\n");
538 if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {
539 printk(
" ** bad parity in PTag0\n");
547 uint32_t datalohi, datalolo, datahi;
548 unsigned long long datalo;
552 for (offset = 0; offset < 4; offset++) {
556 " .set noreorder\n\t"
559 " cache 7, 0(%3)\n\t"
560 " mfc0 %0, $29, 3\n\t"
561 " dmfc0 $1, $28, 3\n\t"
562 " dsrl32 %1, $1, 0 \n\t"
563 " sll %2, $1, 0 \n\t"
565 :
"=r" (datahi),
"=r" (datalohi),
"=r" (datalolo)
566 :
"r" ((way << 13) | addr | (offset << 3)));
567 datalo = ((
unsigned long long)datalohi << 32) | datalolo;
568 ecc = dc_ecc(datalo);
571 bad_ecc |= 1 << (3-
offset);
576 printk(
" %02X-%016llX", datahi, datalo);
580 printk(
" dwords w/ bad ECC: %d %d %d %d\n",
581 !!(bad_ecc & 8), !!(bad_ecc & 4),
582 !!(bad_ecc & 2), !!(bad_ecc & 1));