diff options
author | Bernd Schmidt <bernds_cb1@t-online.de> | 2008-04-24 17:02:33 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@kernel.org> | 2008-04-24 17:02:33 -0400 |
commit | 5d750b9e4f6ca7d366b4954517ff8be9ee07e1bf (patch) | |
tree | 39d05886fdb19f87e77b371688c133b67106931a /arch/blackfin/kernel | |
parent | 00d205a1ce1a24a1a9d9ebfbddbae56021cba826 (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')
-rw-r--r-- | arch/blackfin/kernel/traps.c | 15 |
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 | ||
70 | void *saved_icplb_fault_addr, *saved_dcplb_fault_addr; | ||
71 | |||
70 | int kstack_depth_to_print = 48; | 72 | int kstack_depth_to_print = 48; |
71 | 73 | ||
72 | static void decode_address(char *buf, unsigned long address) | 74 | static 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); |