]> git.sur5r.net Git - u-boot/blobdiff - arch/blackfin/cpu/traps.c
powerpc/85xx: Add recognition of e5500 core
[u-boot] / arch / blackfin / cpu / traps.c
index caaea94106a556d2095a85847967743a3eabfd19..09388aa3d53a15ed8b34d188732ee31eded5499f 100644 (file)
 #include <asm/deferred.h>
 #include "cpu.h"
 
+#ifdef CONFIG_DEBUG_DUMP
+# define ENABLE_DUMP 1
+#else
+# define ENABLE_DUMP 0
+#endif
+
 #define trace_buffer_save(x) \
        do { \
+               if (!ENABLE_DUMP) \
+                       break; \
                (x) = bfin_read_TBUFCTL(); \
                bfin_write_TBUFCTL((x) & ~TBUFEN); \
        } while (0)
 
 #define trace_buffer_restore(x) \
-       bfin_write_TBUFCTL((x))
+       do { \
+               if (!ENABLE_DUMP) \
+                       break; \
+               bfin_write_TBUFCTL((x)); \
+       } while (0);
 
 /* The purpose of this map is to provide a mapping of address<->cplb settings
  * rather than an exact map of what is actually addressable on the part.  This
@@ -82,8 +94,16 @@ int trap_c(struct pt_regs *regs, uint32_t level)
 {
        uint32_t ret = 0;
        uint32_t trapnr = (regs->seqstat & EXCAUSE);
+       unsigned long tflags;
        bool data = false;
 
+       /*
+        * Keep the trace buffer so that a miss here points people
+        * to the right place (their code).  Crashes here rarely
+        * happen.  If they do, only the Blackfin maintainer cares.
+        */
+       trace_buffer_save(tflags);
+
        switch (trapnr) {
        /* 0x26 - Data CPLB Miss */
        case VEC_CPLB_M:
@@ -97,7 +117,7 @@ int trap_c(struct pt_regs *regs, uint32_t level)
                         */
                        if (last_cplb_fault_retx != regs->retx) {
                                last_cplb_fault_retx = regs->retx;
-                               return ret;
+                               break;
                        }
                }
 
@@ -110,7 +130,6 @@ int trap_c(struct pt_regs *regs, uint32_t level)
                uint32_t new_cplb_addr = 0, new_cplb_data = 0;
                static size_t last_evicted;
                size_t i;
-               unsigned long tflags;
 
 #ifdef CONFIG_EXCEPTION_DEFER
                /* This should never happen */
@@ -118,13 +137,6 @@ int trap_c(struct pt_regs *regs, uint32_t level)
                        bfin_panic(regs);
 #endif
 
-               /*
-                * Keep the trace buffer so that a miss here points people
-                * to the right place (their code).  Crashes here rarely
-                * happen.  If they do, only the Blackfin maintainer cares.
-                */
-               trace_buffer_save(tflags);
-
                new_cplb_addr = (data ? bfin_read_DCPLB_FAULT_ADDR() : bfin_read_ICPLB_FAULT_ADDR()) & ~(4 * 1024 * 1024 - 1);
 
                for (i = 0; i < ARRAY_SIZE(bfin_memory_map); ++i) {
@@ -180,7 +192,6 @@ int trap_c(struct pt_regs *regs, uint32_t level)
                for (i = 0; i < 16; ++i)
                        debug("%2i 0x%p 0x%08X\n", i, *CPLB_ADDR++, *CPLB_DATA++);
 
-               trace_buffer_restore(tflags);
                break;
        }
 #ifdef CONFIG_CMD_KGDB
@@ -208,23 +219,21 @@ int trap_c(struct pt_regs *regs, uint32_t level)
 #ifdef CONFIG_CMD_KGDB
                if (level == 3) {
                        /* We need to handle this at EVT5, so try again */
+                       bfin_dump(regs);
                        ret = 1;
                        break;
                }
                if (debugger_exception_handler && (*debugger_exception_handler)(regs))
-                       return 0;
+                       break;
 #endif
                bfin_panic(regs);
        }
+
+       trace_buffer_restore(tflags);
+
        return ret;
 }
 
-#ifdef CONFIG_DEBUG_DUMP
-# define ENABLE_DUMP 1
-#else
-# define ENABLE_DUMP 0
-#endif
-
 #ifndef CONFIG_KALLSYMS
 const char *symbol_lookup(unsigned long addr, unsigned long *caddr)
 {
@@ -364,17 +373,14 @@ void dump(struct pt_regs *fp)
        printf("\n");
 }
 
-void dump_bfin_trace_buffer(void)
+static void _dump_bfin_trace_buffer(void)
 {
        char buf[150];
-       unsigned long tflags;
        int i = 0;
 
        if (!ENABLE_DUMP)
                return;
 
-       trace_buffer_save(tflags);
-
        printf("Hardware Trace:\n");
 
        if (bfin_read_TBUFSTAT() & TBUFCNT) {
@@ -385,16 +391,21 @@ void dump_bfin_trace_buffer(void)
                        printf("     Source : %s\n", buf);
                }
        }
+}
 
+void dump_bfin_trace_buffer(void)
+{
+       unsigned long tflags;
+       trace_buffer_save(tflags);
+       _dump_bfin_trace_buffer();
        trace_buffer_restore(tflags);
 }
 
-void bfin_panic(struct pt_regs *regs)
+void bfin_dump(struct pt_regs *regs)
 {
-       if (ENABLE_DUMP) {
-               unsigned long tflags;
-               trace_buffer_save(tflags);
-       }
+       unsigned long tflags;
+
+       trace_buffer_save(tflags);
 
        puts(
                "\n"
@@ -404,7 +415,16 @@ void bfin_panic(struct pt_regs *regs)
                "\n"
        );
        dump(regs);
-       dump_bfin_trace_buffer();
+       _dump_bfin_trace_buffer();
        puts("\n");
+
+       trace_buffer_restore(tflags);
+}
+
+void bfin_panic(struct pt_regs *regs)
+{
+       unsigned long tflags;
+       trace_buffer_save(tflags);
+       bfin_dump(regs);
        bfin_reset_or_hang();
 }