aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorBarry Song <barry.song@analog.com>2009-11-27 04:18:21 -0500
committerMike Frysinger <vapier@gentoo.org>2009-12-15 00:15:59 -0500
commita00b4fe5ce4b98f7c4457fffdb392d7bfece2e78 (patch)
treec4416dd2c7264aac87cd1d4be948f6ca4379158f /arch/blackfin
parent340a1be1eed07bb46c2f2d853e60234c1d5bb1c3 (diff)
Blackfin: workaround anomaly 05000310
While fetching instructions at the boundary of L1 instruction SRAM, a false External Memory Addressing Error might be triggered. We should ignore this and continue on our way to avoid random crashes. Because hardware errors are not exact in the Blackfin architecture, we need to catch a few more common cases when the code flow changes and the signal is finally delivered. Signed-off-by: Barry Song <barry.song@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/kernel/traps.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 427294c47f1b..e4fd516ce482 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -524,6 +524,36 @@ asmlinkage notrace void trap_c(struct pt_regs *fp)
524 break; 524 break;
525 /* External Memory Addressing Error */ 525 /* External Memory Addressing Error */
526 case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): 526 case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR):
527 if (ANOMALY_05000310) {
528 static unsigned long anomaly_rets;
529
530 if ((fp->pc >= (L1_CODE_START + L1_CODE_LENGTH - 512)) &&
531 (fp->pc < (L1_CODE_START + L1_CODE_LENGTH))) {
532 /*
533 * A false hardware error will happen while fetching at
534 * the L1 instruction SRAM boundary. Ignore it.
535 */
536 anomaly_rets = fp->rets;
537 goto traps_done;
538 } else if (fp->rets == anomaly_rets) {
539 /*
540 * While boundary code returns to a function, at the ret
541 * point, a new false hardware error might occur too based
542 * on tests. Ignore it too.
543 */
544 goto traps_done;
545 } else if ((fp->rets >= (L1_CODE_START + L1_CODE_LENGTH - 512)) &&
546 (fp->rets < (L1_CODE_START + L1_CODE_LENGTH))) {
547 /*
548 * If boundary code calls a function, at the entry point,
549 * a new false hardware error maybe happen based on tests.
550 * Ignore it too.
551 */
552 goto traps_done;
553 } else
554 anomaly_rets = 0;
555 }
556
527 info.si_code = BUS_ADRERR; 557 info.si_code = BUS_ADRERR;
528 sig = SIGBUS; 558 sig = SIGBUS;
529 strerror = KERN_NOTICE HWC_x3(KERN_NOTICE); 559 strerror = KERN_NOTICE HWC_x3(KERN_NOTICE);