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)
        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);
 
 
        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);
        }
 
 
        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);
 
 #include <linux/unistd.h>
 #include <asm/blackfin.h>
 #include <asm/errno.h>
+#include <asm/fixed_code.h>
 #include <asm/thread_info.h>  /* TIF_NEED_RESCHED */
 #include <asm/asm-offsets.h>
 #include <asm/trace.h>
 # define EX_SCRATCH_REG CYCLES
 #endif
 
-#if ANOMALY_05000281
-ENTRY(_safe_speculative_execution)
-       NOP;
-       NOP;
-       NOP;
-       jump _safe_speculative_execution;
-ENDPROC(_safe_speculative_execution)
-#endif
-
 #ifdef CONFIG_EXCPT_IRQ_SYSC_L1
 .section .l1.text
 #else
        [p4] = p5;
        csync;
 
+       p4.l = lo(DCPLB_FAULT_ADDR);
+       p4.h = hi(DCPLB_FAULT_ADDR);
+       r7 = [p4];
+       p5.h = _saved_dcplb_fault_addr;
+       p5.l = _saved_dcplb_fault_addr;
+       [p5] = r7;
+
+       r7 = [p4 + (ICPLB_FAULT_ADDR - DCPLB_FAULT_ADDR)];
+       p5.h = _saved_icplb_fault_addr;
+       p5.l = _saved_icplb_fault_addr;
+       [p5] = r7;
+
+       p4.l = __retx;
+       p4.h = __retx;
+       r6 = retx;
+       [p4] = r6;
+       p4.l = lo(SAFE_USER_INSTRUCTION);
+       p4.h = hi(SAFE_USER_INSTRUCTION);
+       retx = p4;
+
        /* Disable all interrupts, but make sure level 5 is enabled so
         * we can switch to that level.  Save the old mask.  */
        cli r6;
        r6 = 0x3f;
        sti r6;
 
-       /* Save the excause into a circular buffer, in case the instruction
-        * which caused this excecptions causes others.
-        */
-       P5.l = _in_ptr_excause;
-       P5.h = _in_ptr_excause;
-       R7 = [P5];
-       R7 += 4;
-       R6 = 0xF;
-       R7 = R7 & R6;
-       [P5] = R7;
-       R6.l = _excause_circ_buf;
-       R6.h = _excause_circ_buf;
-       R7 = R7 + R6;
-       p5 = R7;
-       R6 = SEQSTAT;
-       [P5] = R6;
-
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
        SP = EX_SCRATCH_REG;
 ENTRY(_exception_to_level5)
        SAVE_ALL_SYS
 
+       p4.l = __retx;
+       p4.h = __retx;
+       r6 = [p4];
+       [sp + PT_PC] = r6;
+
        /* Restore interrupt mask.  We haven't pushed RETI, so this
         * doesn't enable interrupts until we return from this handler.  */
        p4.l = _excpt_saved_imask;
        r0 = [p2];              /* Read current IPEND */
        [sp + PT_IPEND] = r0;   /* Store IPEND */
 
-       /* Pop the excause from the circular buffer and push it on the stack
-        * (in the right place - if you change the location of SEQSTAT, you
-        * must change this offset.
-        */
-.L_excep_to_5_again:
-       P5.l = _out_ptr_excause;
-       P5.h = _out_ptr_excause;
-       R7 = [P5];
-       R7 += 4;
-       R6 = 0xF;
-       R7 = R7 & R6;
-       [P5] = R7;
-       R6.l = _excause_circ_buf;
-       R6.h = _excause_circ_buf;
-       R7 = R7 + R6;
-       P5 = R7;
-       R1 = [P5];
-       [SP + PT_SEQSTAT] = r1;
-
        r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
        SP += -12;
        call _trap_c;
        SP += 12;
 
-       /* See if anything else is in the exception buffer
-        * if there is, process it
-        */
-       P5.l = _out_ptr_excause;
-       P5.h = _out_ptr_excause;
-       P4.l = _in_ptr_excause;
-       P4.h = _in_ptr_excause;
-       R6 = [P5];
-       R7 = [P4];
-       CC = R6 == R7;
-       if ! CC JUMP .L_excep_to_5_again
-
        call _ret_from_exception;
        RESTORE_ALL_SYS
        rti;
        [p0] = p1;
        csync;
 #if ANOMALY_05000281
-       r0.l = _safe_speculative_execution;
-       r0.h = _safe_speculative_execution;
+       r0.l = lo(SAFE_USER_INSTRUCTION);
+       r0.h = hi(SAFE_USER_INSTRUCTION);
        reti = r0;
 #endif
        r0 = 0x801f (z);
 
 ENTRY(_lower_to_irq14)
 #if ANOMALY_05000281
-       r0.l = _safe_speculative_execution;
-       r0.h = _safe_speculative_execution;
+       r0.l = lo(SAFE_USER_INSTRUCTION);
+       r0.h = hi(SAFE_USER_INSTRUCTION);
        reti = r0;
 #endif
        r0 = 0x401f;
        rti;
 ENDPROC(_lower_to_irq14)
 
-/* Make sure when we start, that the circular buffer is initialized properly
- * R0 and P0 are call clobbered, so we can use them here.
- */
-ENTRY(_init_exception_buff)
-       r0 = 0;
-       p0.h = _in_ptr_excause;
-       p0.l = _in_ptr_excause;
-       [p0] = r0;
-       p0.h = _out_ptr_excause;
-       p0.l = _out_ptr_excause;
-       [p0] = r0;
-       rts;
-ENDPROC(_init_exception_buff)
-
 /* We handle this 100% in exception space - to reduce overhead
  * Only potiential problem is if the software buffer gets swapped out of the
  * CPLB table - then double fault. - so we don't let this happen in other places
 _last_cplb_fault_retx:
        .long 0;
 #endif
-/*
- * Single instructions can have multiple faults, which need to be
- * handled by traps.c, in irq5. We store the exception cause to ensure
- * we don't miss a double fault condition
- */
-ENTRY(_in_ptr_excause)
-       .long 0;
-ENTRY(_out_ptr_excause)
+       /* Used to save the real RETX when temporarily storing a safe
+        * return address.  */
+__retx:
        .long 0;
-ALIGN
-ENTRY(_excause_circ_buf)
-       .rept 4
-       .long 0
-       .endr