[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>

diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index d0f6754..5b84707 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -67,6 +67,8 @@
 	CSYNC();
 }
 
+void *saved_icplb_fault_addr, *saved_dcplb_fault_addr;
+
 int kstack_depth_to_print = 48;
 
 static void decode_address(char *buf, unsigned long address)
@@ -703,10 +705,7 @@
 	unsigned short *addr, *erraddr, val = 0, err = 0;
 	char sti = 0, buf[6];
 
-	if (unlikely((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR))
-		erraddr = (void *)fp->pc;
-	else
-		erraddr = (void *)fp->retx;
+	erraddr = (void *)fp->pc;
 
 	printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr);
 
@@ -830,9 +829,9 @@
 
 	if (((long)fp->seqstat &  SEQSTAT_EXCAUSE) &&
 	    (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) {
-		decode_address(buf, bfin_read_DCPLB_FAULT_ADDR());
+		decode_address(buf, saved_dcplb_fault_addr);
 		printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf);
-		decode_address(buf, bfin_read_ICPLB_FAULT_ADDR());
+		decode_address(buf, saved_icplb_fault_addr);
 		printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf);
 	}
 
@@ -940,8 +939,8 @@
 
 	oops_in_progress = 1;
 
-	printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR());
-	printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR());
+	printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", saved_dcplb_fault_addr);
+	printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", saved_icplb_fault_addr);
 	dump_bfin_process(fp);
 	dump_bfin_mem(fp);
 	show_regs(fp);