aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/traps.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds_cb1@t-online.de>2008-04-24 17:02:33 -0400
committerBryan Wu <cooloney@kernel.org>2008-04-24 17:02:33 -0400
commit5d750b9e4f6ca7d366b4954517ff8be9ee07e1bf (patch)
tree39d05886fdb19f87e77b371688c133b67106931a /arch/blackfin/kernel/traps.c
parent00d205a1ce1a24a1a9d9ebfbddbae56021cba826 (diff)
[Blackfin] arch: Remove the circular buffering mechanism for exceptions
Remove the circular buffering mechanism for exceptions. Instead, point RETX at a safe location from which to fetch three NOPs. This safe location is now in the fixed code area, and also used for certain anomaly workarounds, to ensure that user space can find a valid ICPLB when things are built with CONFIG_MPU. Also, save I/DCPLB_FAULT_ADDRESS when lowering to level 5, since the hardware reg is valid only at exception level. Signed-off-by: Bernd Schmidt <bernds_cb1@t-online.de> Signed-off-by: Bryan Wu <cooloney@kernel.org>
Diffstat (limited to 'arch/blackfin/kernel/traps.c')
-rw-r--r--arch/blackfin/kernel/traps.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index d0f675422074..5b847070dae5 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -67,6 +67,8 @@ void __init trap_init(void)
67 CSYNC(); 67 CSYNC();
68} 68}
69 69
70void *saved_icplb_fault_addr, *saved_dcplb_fault_addr;
71
70int kstack_depth_to_print = 48; 72int kstack_depth_to_print = 48;
71 73
72static void decode_address(char *buf, unsigned long address) 74static void decode_address(char *buf, unsigned long address)
@@ -703,10 +705,7 @@ void dump_bfin_mem(struct pt_regs *fp)
703 unsigned short *addr, *erraddr, val = 0, err = 0; 705 unsigned short *addr, *erraddr, val = 0, err = 0;
704 char sti = 0, buf[6]; 706 char sti = 0, buf[6];
705 707
706 if (unlikely((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR)) 708 erraddr = (void *)fp->pc;
707 erraddr = (void *)fp->pc;
708 else
709 erraddr = (void *)fp->retx;
710 709
711 printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); 710 printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr);
712 711
@@ -830,9 +829,9 @@ unlock:
830 829
831 if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && 830 if (((long)fp->seqstat & SEQSTAT_EXCAUSE) &&
832 (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { 831 (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) {
833 decode_address(buf, bfin_read_DCPLB_FAULT_ADDR()); 832 decode_address(buf, saved_dcplb_fault_addr);
834 printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); 833 printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf);
835 decode_address(buf, bfin_read_ICPLB_FAULT_ADDR()); 834 decode_address(buf, saved_icplb_fault_addr);
836 printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); 835 printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf);
837 } 836 }
838 837
@@ -940,8 +939,8 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
940 939
941 oops_in_progress = 1; 940 oops_in_progress = 1;
942 941
943 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR()); 942 printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", saved_dcplb_fault_addr);
944 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR()); 943 printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", saved_icplb_fault_addr);
945 dump_bfin_process(fp); 944 dump_bfin_process(fp);
946 dump_bfin_mem(fp); 945 dump_bfin_mem(fp);
947 show_regs(fp); 946 show_regs(fp);