Blackfin: workaround anomaly 05000227
authorMike Frysinger <vapier@gentoo.org>
Fri, 24 Apr 2009 03:55:41 +0000 (03:55 +0000)
committerMike Frysinger <vapier@gentoo.org>
Fri, 12 Jun 2009 10:11:32 +0000 (06:11 -0400)
Workaround anomaly 05000227 by only using the scratch pad for stack when
absolutely necessary.  The core code which reprograms clocks really only
touches MMRs directly with constants.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
arch/blackfin/mach-common/head.S

index 698d4c05947e8ba48a21320344a8fc3f93162c00..01d62ff3cd28efd555757e9e8b7f6bea0e5488f2 100644 (file)
@@ -30,8 +30,6 @@ ENTRY(__init_clear_bss)
        rts;
 ENDPROC(__init_clear_bss)
 
-#define INITIAL_STACK  (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
-
 ENTRY(__start)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
@@ -148,8 +146,8 @@ ENTRY(__start)
 #endif
 
        /* Initialize stack pointer */
-       sp.l = lo(INITIAL_STACK);
-       sp.h = hi(INITIAL_STACK);
+       sp.l = _init_thread_union;
+       sp.h = _init_thread_union;
        fp = sp;
        usp = sp;
 
@@ -189,7 +187,15 @@ ENTRY(__start)
        /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
        call _bfin_relocate_l1_mem;
 #ifdef CONFIG_BFIN_KERNEL_CLOCK
+       /* Only use on-chip scratch space for stack when absolutely required
+        * to avoid Anomaly 05000227 ... we know the init_clocks() func only
+        * uses L1 text and stack space and no other memory region.
+        */
+# define KERNEL_CLOCK_STACK (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
+       sp.l = lo(KERNEL_CLOCK_STACK);
+       sp.h = hi(KERNEL_CLOCK_STACK);
        call _init_clocks;
+       sp = usp;       /* usp hasnt been touched, so restore from there */
 #endif
 
        /* This section keeps the processor in supervisor mode
@@ -243,9 +249,7 @@ ENTRY(_real_start)
        call _cmdline_init;
 
        /* Load the current thread pointer and stack */
-       sp.l = _init_thread_union;
-       sp.h = _init_thread_union;
-       p1 = THREAD_SIZE (z);
+       p1 = THREAD_SIZE + 4 (z);       /* +4 is for reti loading */
        sp = sp + p1;
        usp = sp;
        fp = sp;