[Blackfin] arch: fix bug - when using trace buffer with CONFIG_MPU enabled.
authorBernd Schmidt <bernds_cb1@t-online.de>
Tue, 22 Apr 2008 23:17:34 +0000 (07:17 +0800)
committerBryan Wu <cooloney@kernel.org>
Tue, 22 Apr 2008 23:17:34 +0000 (07:17 +0800)
There were a couple of problems with the way the trace buffer state
is saved/restored in assembly.  The DEBUG_HWTRACE_SAVE/RESTORE macros
save a value to the stack, which is not immediately obvious; the CPLB
exception code needed changes to load the correct value of the stack
pointer.  The other problem is that the SAVE/RESTORE macros weren't
pushing and popping the value downwards on the stack, but rather moving
it _upwards_, which is of course completely broken.

We also need to make sure there's a matching DEBUG_HWTRACE_RESTORE in
the error case of the CPLB handler.

Signed-off-by: Bernd Schmidt <bernds_cb1@t-online.de>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
arch/blackfin/mach-common/entry.S
include/asm-blackfin/trace.h

index cee54ce..a504c65 100644 (file)
@@ -121,10 +121,14 @@ ENTRY(_ex_icplb_miss)
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
        SAVE_ALL_SYS
-       DEBUG_HWTRACE_SAVE(p5, r7)
 #ifdef CONFIG_MPU
+       /* We must load R1 here, _before_ DEBUG_HWTRACE_SAVE, since that
+        * will change the stack pointer.  */
        R0 = SEQSTAT;
        R1 = SP;
+#endif
+       DEBUG_HWTRACE_SAVE(p5, r7)
+#ifdef CONFIG_MPU
        sp += -12;
        call _cplb_hdr;
        sp += 12;
@@ -191,6 +195,7 @@ ENTRY(_bfin_return_from_exception)
 ENDPROC(_bfin_return_from_exception)
 
 ENTRY(_handle_bad_cplb)
+       DEBUG_HWTRACE_RESTORE(p5, r7)
        /* To get here, we just tried and failed to change a CPLB
         * so, handle things in trap_c (C code), by lowering to
         * IRQ5, just like we normally do. Since this is not a
index ef18afb..312b596 100644 (file)
@@ -62,14 +62,14 @@ extern unsigned long software_trace_buff[];
        preg.L = LO(TBUFCTL); \
        preg.H = HI(TBUFCTL); \
        dreg = [preg]; \
-       [sp++] = dreg; \
+       [--sp] = dreg; \
        dreg = 0x1; \
        [preg] = dreg;
 
 #define trace_buffer_restore(preg, dreg) \
        preg.L = LO(TBUFCTL); \
        preg.H = HI(TBUFCTL); \
-       dreg = [sp--]; \
+       dreg = [sp++]; \
        [preg] = dreg;
 
 #else /* CONFIG_DEBUG_BFIN_HWTRACE_ON */