aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/cerr-sb1.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm/cerr-sb1.c')
-rw-r--r--arch/mips/mm/cerr-sb1.c133
1 files changed, 67 insertions, 66 deletions
diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
index e19fbb9ee47f..4c72e650f9b6 100644
--- a/arch/mips/mm/cerr-sb1.c
+++ b/arch/mips/mm/cerr-sb1.c
@@ -77,66 +77,66 @@ static uint32_t extract_dc(unsigned short addr, int data);
77static inline void breakout_errctl(unsigned int val) 77static inline void breakout_errctl(unsigned int val)
78{ 78{
79 if (val & CP0_ERRCTL_RECOVERABLE) 79 if (val & CP0_ERRCTL_RECOVERABLE)
80 prom_printf(" recoverable"); 80 printk(" recoverable");
81 if (val & CP0_ERRCTL_DCACHE) 81 if (val & CP0_ERRCTL_DCACHE)
82 prom_printf(" dcache"); 82 printk(" dcache");
83 if (val & CP0_ERRCTL_ICACHE) 83 if (val & CP0_ERRCTL_ICACHE)
84 prom_printf(" icache"); 84 printk(" icache");
85 if (val & CP0_ERRCTL_MULTIBUS) 85 if (val & CP0_ERRCTL_MULTIBUS)
86 prom_printf(" multiple-buserr"); 86 printk(" multiple-buserr");
87 prom_printf("\n"); 87 printk("\n");
88} 88}
89 89
90static inline void breakout_cerri(unsigned int val) 90static inline void breakout_cerri(unsigned int val)
91{ 91{
92 if (val & CP0_CERRI_TAG_PARITY) 92 if (val & CP0_CERRI_TAG_PARITY)
93 prom_printf(" tag-parity"); 93 printk(" tag-parity");
94 if (val & CP0_CERRI_DATA_PARITY) 94 if (val & CP0_CERRI_DATA_PARITY)
95 prom_printf(" data-parity"); 95 printk(" data-parity");
96 if (val & CP0_CERRI_EXTERNAL) 96 if (val & CP0_CERRI_EXTERNAL)
97 prom_printf(" external"); 97 printk(" external");
98 prom_printf("\n"); 98 printk("\n");
99} 99}
100 100
101static inline void breakout_cerrd(unsigned int val) 101static inline void breakout_cerrd(unsigned int val)
102{ 102{
103 switch (val & CP0_CERRD_CAUSES) { 103 switch (val & CP0_CERRD_CAUSES) {
104 case CP0_CERRD_LOAD: 104 case CP0_CERRD_LOAD:
105 prom_printf(" load,"); 105 printk(" load,");
106 break; 106 break;
107 case CP0_CERRD_STORE: 107 case CP0_CERRD_STORE:
108 prom_printf(" store,"); 108 printk(" store,");
109 break; 109 break;
110 case CP0_CERRD_FILLWB: 110 case CP0_CERRD_FILLWB:
111 prom_printf(" fill/wb,"); 111 printk(" fill/wb,");
112 break; 112 break;
113 case CP0_CERRD_COHERENCY: 113 case CP0_CERRD_COHERENCY:
114 prom_printf(" coherency,"); 114 printk(" coherency,");
115 break; 115 break;
116 case CP0_CERRD_DUPTAG: 116 case CP0_CERRD_DUPTAG:
117 prom_printf(" duptags,"); 117 printk(" duptags,");
118 break; 118 break;
119 default: 119 default:
120 prom_printf(" NO CAUSE,"); 120 printk(" NO CAUSE,");
121 break; 121 break;
122 } 122 }
123 if (!(val & CP0_CERRD_TYPES)) 123 if (!(val & CP0_CERRD_TYPES))
124 prom_printf(" NO TYPE"); 124 printk(" NO TYPE");
125 else { 125 else {
126 if (val & CP0_CERRD_MULTIPLE) 126 if (val & CP0_CERRD_MULTIPLE)
127 prom_printf(" multi-err"); 127 printk(" multi-err");
128 if (val & CP0_CERRD_TAG_STATE) 128 if (val & CP0_CERRD_TAG_STATE)
129 prom_printf(" tag-state"); 129 printk(" tag-state");
130 if (val & CP0_CERRD_TAG_ADDRESS) 130 if (val & CP0_CERRD_TAG_ADDRESS)
131 prom_printf(" tag-address"); 131 printk(" tag-address");
132 if (val & CP0_CERRD_DATA_SBE) 132 if (val & CP0_CERRD_DATA_SBE)
133 prom_printf(" data-SBE"); 133 printk(" data-SBE");
134 if (val & CP0_CERRD_DATA_DBE) 134 if (val & CP0_CERRD_DATA_DBE)
135 prom_printf(" data-DBE"); 135 printk(" data-DBE");
136 if (val & CP0_CERRD_EXTERNAL) 136 if (val & CP0_CERRD_EXTERNAL)
137 prom_printf(" external"); 137 printk(" external");
138 } 138 }
139 prom_printf("\n"); 139 printk("\n");
140} 140}
141 141
142#ifndef CONFIG_SIBYTE_BUS_WATCHER 142#ifndef CONFIG_SIBYTE_BUS_WATCHER
@@ -157,18 +157,18 @@ static void check_bus_watcher(void)
157 l2_tag = in64(IO_SPACE_BASE | A_L2_ECC_TAG); 157 l2_tag = in64(IO_SPACE_BASE | A_L2_ECC_TAG);
158#endif 158#endif
159 memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS)); 159 memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
160 prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); 160 printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
161 prom_printf("\nLast recorded signature:\n"); 161 printk("\nLast recorded signature:\n");
162 prom_printf("Request %02x from %d, answered by %d with Dcode %d\n", 162 printk("Request %02x from %d, answered by %d with Dcode %d\n",
163 (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), 163 (unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
164 (int)(G_SCD_BERR_TID(status) >> 6), 164 (int)(G_SCD_BERR_TID(status) >> 6),
165 (int)G_SCD_BERR_RID(status), 165 (int)G_SCD_BERR_RID(status),
166 (int)G_SCD_BERR_DCODE(status)); 166 (int)G_SCD_BERR_DCODE(status));
167#ifdef DUMP_L2_ECC_TAG_ON_ERROR 167#ifdef DUMP_L2_ECC_TAG_ON_ERROR
168 prom_printf("Last L2 tag w/ bad ECC: %016llx\n", l2_tag); 168 printk("Last L2 tag w/ bad ECC: %016llx\n", l2_tag);
169#endif 169#endif
170 } else { 170 } else {
171 prom_printf("Bus watcher indicates no error\n"); 171 printk("Bus watcher indicates no error\n");
172 } 172 }
173} 173}
174#else 174#else
@@ -177,8 +177,8 @@ extern void check_bus_watcher(void);
177 177
178asmlinkage void sb1_cache_error(void) 178asmlinkage void sb1_cache_error(void)
179{ 179{
180 uint64_t cerr_dpa;
181 uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; 180 uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
181 unsigned long long cerr_dpa;
182 182
183#ifdef CONFIG_SIBYTE_BW_TRACE 183#ifdef CONFIG_SIBYTE_BW_TRACE
184 /* Freeze the trace buffer now */ 184 /* Freeze the trace buffer now */
@@ -187,11 +187,11 @@ asmlinkage void sb1_cache_error(void)
187#else 187#else
188 csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG); 188 csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
189#endif 189#endif
190 prom_printf("Trace buffer frozen\n"); 190 printk("Trace buffer frozen\n");
191#endif 191#endif
192 192
193 prom_printf("Cache error exception on CPU %x:\n", 193 printk("Cache error exception on CPU %x:\n",
194 (read_c0_prid() >> 25) & 0x7); 194 (read_c0_prid() >> 25) & 0x7);
195 195
196 __asm__ __volatile__ ( 196 __asm__ __volatile__ (
197 " .set push\n\t" 197 " .set push\n\t"
@@ -209,43 +209,43 @@ asmlinkage void sb1_cache_error(void)
209 "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); 209 "=r" (dpahi), "=r" (dpalo), "=r" (eepc));
210 210
211 cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; 211 cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo;
212 prom_printf(" c0_errorepc == %08x\n", eepc); 212 printk(" c0_errorepc == %08x\n", eepc);
213 prom_printf(" c0_errctl == %08x", errctl); 213 printk(" c0_errctl == %08x", errctl);
214 breakout_errctl(errctl); 214 breakout_errctl(errctl);
215 if (errctl & CP0_ERRCTL_ICACHE) { 215 if (errctl & CP0_ERRCTL_ICACHE) {
216 prom_printf(" c0_cerr_i == %08x", cerr_i); 216 printk(" c0_cerr_i == %08x", cerr_i);
217 breakout_cerri(cerr_i); 217 breakout_cerri(cerr_i);
218 if (CP0_CERRI_IDX_VALID(cerr_i)) { 218 if (CP0_CERRI_IDX_VALID(cerr_i)) {
219 /* Check index of EPC, allowing for delay slot */ 219 /* Check index of EPC, allowing for delay slot */
220 if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) && 220 if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) &&
221 ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4))) 221 ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4)))
222 prom_printf(" cerr_i idx doesn't match eepc\n"); 222 printk(" cerr_i idx doesn't match eepc\n");
223 else { 223 else {
224 res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, 224 res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK,
225 (cerr_i & CP0_CERRI_DATA) != 0); 225 (cerr_i & CP0_CERRI_DATA) != 0);
226 if (!(res & cerr_i)) 226 if (!(res & cerr_i))
227 prom_printf("...didn't see indicated icache problem\n"); 227 printk("...didn't see indicated icache problem\n");
228 } 228 }
229 } 229 }
230 } 230 }
231 if (errctl & CP0_ERRCTL_DCACHE) { 231 if (errctl & CP0_ERRCTL_DCACHE) {
232 prom_printf(" c0_cerr_d == %08x", cerr_d); 232 printk(" c0_cerr_d == %08x", cerr_d);
233 breakout_cerrd(cerr_d); 233 breakout_cerrd(cerr_d);
234 if (CP0_CERRD_DPA_VALID(cerr_d)) { 234 if (CP0_CERRD_DPA_VALID(cerr_d)) {
235 prom_printf(" c0_cerr_dpa == %010llx\n", cerr_dpa); 235 printk(" c0_cerr_dpa == %010llx\n", cerr_dpa);
236 if (!CP0_CERRD_IDX_VALID(cerr_d)) { 236 if (!CP0_CERRD_IDX_VALID(cerr_d)) {
237 res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, 237 res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK,
238 (cerr_d & CP0_CERRD_DATA) != 0); 238 (cerr_d & CP0_CERRD_DATA) != 0);
239 if (!(res & cerr_d)) 239 if (!(res & cerr_d))
240 prom_printf("...didn't see indicated dcache problem\n"); 240 printk("...didn't see indicated dcache problem\n");
241 } else { 241 } else {
242 if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) 242 if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK))
243 prom_printf(" cerr_d idx doesn't match cerr_dpa\n"); 243 printk(" cerr_d idx doesn't match cerr_dpa\n");
244 else { 244 else {
245 res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, 245 res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK,
246 (cerr_d & CP0_CERRD_DATA) != 0); 246 (cerr_d & CP0_CERRD_DATA) != 0);
247 if (!(res & cerr_d)) 247 if (!(res & cerr_d))
248 prom_printf("...didn't see indicated problem\n"); 248 printk("...didn't see indicated problem\n");
249 } 249 }
250 } 250 }
251 } 251 }
@@ -329,12 +329,13 @@ static uint32_t extract_ic(unsigned short addr, int data)
329{ 329{
330 unsigned short way; 330 unsigned short way;
331 int valid; 331 int valid;
332 uint64_t taglo, va, tlo_tmp;
333 uint32_t taghi, taglolo, taglohi; 332 uint32_t taghi, taglolo, taglohi;
333 unsigned long long taglo, va;
334 uint64_t tlo_tmp;
334 uint8_t lru; 335 uint8_t lru;
335 int res = 0; 336 int res = 0;
336 337
337 prom_printf("Icache index 0x%04x ", addr); 338 printk("Icache index 0x%04x ", addr);
338 for (way = 0; way < 4; way++) { 339 for (way = 0; way < 4; way++) {
339 /* Index-load-tag-I */ 340 /* Index-load-tag-I */
340 __asm__ __volatile__ ( 341 __asm__ __volatile__ (
@@ -354,7 +355,7 @@ static uint32_t extract_ic(unsigned short addr, int data)
354 taglo = ((unsigned long long)taglohi << 32) | taglolo; 355 taglo = ((unsigned long long)taglohi << 32) | taglolo;
355 if (way == 0) { 356 if (way == 0) {
356 lru = (taghi >> 14) & 0xff; 357 lru = (taghi >> 14) & 0xff;
357 prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", 358 printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
358 ((addr >> 5) & 0x3), /* bank */ 359 ((addr >> 5) & 0x3), /* bank */
359 ((addr >> 7) & 0x3f), /* index */ 360 ((addr >> 7) & 0x3f), /* index */
360 (lru & 0x3), 361 (lru & 0x3),
@@ -369,19 +370,19 @@ static uint32_t extract_ic(unsigned short addr, int data)
369 if (valid) { 370 if (valid) {
370 tlo_tmp = taglo & 0xfff3ff; 371 tlo_tmp = taglo & 0xfff3ff;
371 if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { 372 if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {
372 prom_printf(" ** bad parity in VTag0/G/ASID\n"); 373 printk(" ** bad parity in VTag0/G/ASID\n");
373 res |= CP0_CERRI_TAG_PARITY; 374 res |= CP0_CERRI_TAG_PARITY;
374 } 375 }
375 if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { 376 if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {
376 prom_printf(" ** bad parity in R/VTag1\n"); 377 printk(" ** bad parity in R/VTag1\n");
377 res |= CP0_CERRI_TAG_PARITY; 378 res |= CP0_CERRI_TAG_PARITY;
378 } 379 }
379 } 380 }
380 if (valid ^ ((taghi >> 27) & 1)) { 381 if (valid ^ ((taghi >> 27) & 1)) {
381 prom_printf(" ** bad parity for valid bit\n"); 382 printk(" ** bad parity for valid bit\n");
382 res |= CP0_CERRI_TAG_PARITY; 383 res |= CP0_CERRI_TAG_PARITY;
383 } 384 }
384 prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", 385 printk(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n",
385 way, va, valid, taghi, taglo); 386 way, va, valid, taghi, taglo);
386 387
387 if (data) { 388 if (data) {
@@ -407,21 +408,21 @@ static uint32_t extract_ic(unsigned short addr, int data)
407 : "r" ((way << 13) | addr | (offset << 3))); 408 : "r" ((way << 13) | addr | (offset << 3)));
408 predecode = (datahi >> 8) & 0xff; 409 predecode = (datahi >> 8) & 0xff;
409 if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { 410 if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) {
410 prom_printf(" ** bad parity in predecode\n"); 411 printk(" ** bad parity in predecode\n");
411 res |= CP0_CERRI_DATA_PARITY; 412 res |= CP0_CERRI_DATA_PARITY;
412 } 413 }
413 /* XXXKW should/could check predecode bits themselves */ 414 /* XXXKW should/could check predecode bits themselves */
414 if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { 415 if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {
415 prom_printf(" ** bad parity in instruction a\n"); 416 printk(" ** bad parity in instruction a\n");
416 res |= CP0_CERRI_DATA_PARITY; 417 res |= CP0_CERRI_DATA_PARITY;
417 } 418 }
418 if ((datahi & 0xf) ^ inst_parity(instb)) { 419 if ((datahi & 0xf) ^ inst_parity(instb)) {
419 prom_printf(" ** bad parity in instruction b\n"); 420 printk(" ** bad parity in instruction b\n");
420 res |= CP0_CERRI_DATA_PARITY; 421 res |= CP0_CERRI_DATA_PARITY;
421 } 422 }
422 prom_printf(" %05X-%08X%08X", datahi, insta, instb); 423 printk(" %05X-%08X%08X", datahi, insta, instb);
423 } 424 }
424 prom_printf("\n"); 425 printk("\n");
425 } 426 }
426 } 427 }
427 return res; 428 return res;
@@ -484,12 +485,12 @@ static uint32_t extract_dc(unsigned short addr, int data)
484{ 485{
485 int valid, way; 486 int valid, way;
486 unsigned char state; 487 unsigned char state;
487 uint64_t taglo, pa;
488 uint32_t taghi, taglolo, taglohi; 488 uint32_t taghi, taglolo, taglohi;
489 unsigned long long taglo, pa;
489 uint8_t ecc, lru; 490 uint8_t ecc, lru;
490 int res = 0; 491 int res = 0;
491 492
492 prom_printf("Dcache index 0x%04x ", addr); 493 printk("Dcache index 0x%04x ", addr);
493 for (way = 0; way < 4; way++) { 494 for (way = 0; way < 4; way++) {
494 __asm__ __volatile__ ( 495 __asm__ __volatile__ (
495 " .set push\n\t" 496 " .set push\n\t"
@@ -509,7 +510,7 @@ static uint32_t extract_dc(unsigned short addr, int data)
509 pa = (taglo & 0xFFFFFFE000ULL) | addr; 510 pa = (taglo & 0xFFFFFFE000ULL) | addr;
510 if (way == 0) { 511 if (way == 0) {
511 lru = (taghi >> 14) & 0xff; 512 lru = (taghi >> 14) & 0xff;
512 prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", 513 printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
513 ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ 514 ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */
514 ((addr >> 6) & 0x3f), /* index */ 515 ((addr >> 6) & 0x3f), /* index */
515 (lru & 0x3), 516 (lru & 0x3),
@@ -519,15 +520,15 @@ static uint32_t extract_dc(unsigned short addr, int data)
519 } 520 }
520 state = (taghi >> 25) & 0x1f; 521 state = (taghi >> 25) & 0x1f;
521 valid = DC_TAG_VALID(state); 522 valid = DC_TAG_VALID(state);
522 prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", 523 printk(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n",
523 way, pa, dc_state_str(state), state, taghi, taglo); 524 way, pa, dc_state_str(state), state, taghi, taglo);
524 if (valid) { 525 if (valid) {
525 if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { 526 if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {
526 prom_printf(" ** bad parity in PTag1\n"); 527 printk(" ** bad parity in PTag1\n");
527 res |= CP0_CERRD_TAG_ADDRESS; 528 res |= CP0_CERRD_TAG_ADDRESS;
528 } 529 }
529 if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { 530 if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {
530 prom_printf(" ** bad parity in PTag0\n"); 531 printk(" ** bad parity in PTag0\n");
531 res |= CP0_CERRD_TAG_ADDRESS; 532 res |= CP0_CERRD_TAG_ADDRESS;
532 } 533 }
533 } else { 534 } else {
@@ -535,8 +536,8 @@ static uint32_t extract_dc(unsigned short addr, int data)
535 } 536 }
536 537
537 if (data) { 538 if (data) {
538 uint64_t datalo;
539 uint32_t datalohi, datalolo, datahi; 539 uint32_t datalohi, datalolo, datahi;
540 unsigned long long datalo;
540 int offset; 541 int offset;
541 char bad_ecc = 0; 542 char bad_ecc = 0;
542 543
@@ -567,13 +568,13 @@ static uint32_t extract_dc(unsigned short addr, int data)
567 } 568 }
568 res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; 569 res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
569 } 570 }
570 prom_printf(" %02X-%016llX", datahi, datalo); 571 printk(" %02X-%016llX", datahi, datalo);
571 } 572 }
572 prom_printf("\n"); 573 printk("\n");
573 if (bad_ecc) 574 if (bad_ecc)
574 prom_printf(" dwords w/ bad ECC: %d %d %d %d\n", 575 printk(" dwords w/ bad ECC: %d %d %d %d\n",
575 !!(bad_ecc & 8), !!(bad_ecc & 4), 576 !!(bad_ecc & 8), !!(bad_ecc & 4),
576 !!(bad_ecc & 2), !!(bad_ecc & 1)); 577 !!(bad_ecc & 2), !!(bad_ecc & 1));
577 } 578 }
578 } 579 }
579 return res; 580 return res;