xtensa: fixes for configs without loop option
authorMax Filippov <jcmvbkbc@gmail.com>
Thu, 24 Sep 2015 20:11:53 +0000 (23:11 +0300)
committerMax Filippov <jcmvbkbc@gmail.com>
Mon, 2 Nov 2015 15:02:47 +0000 (18:02 +0300)
Build-time fixes:
- make lbeg/lend/lcount save/restore conditional on kernel entry;
- don't clear lcount in platform_restart functions unconditionally.

Run-time fixes:
- use correct end of range register in __endla paired with __loopt, not
  the unused temporary register. This fixes .bss zero-initialization.
  Update comments in asmmacro.h;
- don't clobber a10 in the usercopy that leads to access to unmapped
  memory.

Cc: <stable@vger.kernel.org>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
arch/xtensa/include/asm/asmmacro.h
arch/xtensa/kernel/entry.S
arch/xtensa/kernel/head.S
arch/xtensa/lib/usercopy.S
arch/xtensa/platforms/iss/setup.c
arch/xtensa/platforms/xt2000/setup.c
arch/xtensa/platforms/xtfpga/setup.c

index 755320f6e0bcb4b698fe5f8ffcd3d8dc2086bd12..746dcc8b5abc87774a7c099447395fa3f5992f9b 100644 (file)
  * __loop  as
  *        restart loop. 'as' register must not have been modified!
  *
- * __endla ar, at, incr
+ * __endla ar, as, incr
  *        ar   start address (modified)
- *        as   scratch register used by macro
+ *        as   scratch register used by __loops/__loopi macros or
+ *             end address used by __loopt macro
  *        inc  increment
  */
 
@@ -97,7 +98,7 @@
        .endm
 
 /*
- * loop from ar to ax
+ * loop from ar to as
  */
 
        .macro  __loopt ar, as, at, incr_log2
index 504130357597f937cf9d4381c5f9201d9f3197a6..db5c1765b413745fa5cc876adb2e4468f7770439 100644 (file)
@@ -367,8 +367,10 @@ common_exception:
        s32i    a2, a1, PT_SYSCALL
        movi    a2, 0
        s32i    a3, a1, PT_EXCVADDR
+#if XCHAL_HAVE_LOOPS
        xsr     a2, lcount
        s32i    a2, a1, PT_LCOUNT
+#endif
 
        /* It is now save to restore the EXC_TABLE_FIXUP variable. */
 
@@ -429,11 +431,12 @@ common_exception:
        rsync                           # PS.WOE => rsync => overflow
 
        /* Save lbeg, lend */
-
+#if XCHAL_HAVE_LOOPS
        rsr     a4, lbeg
        rsr     a3, lend
        s32i    a4, a1, PT_LBEG
        s32i    a3, a1, PT_LEND
+#endif
 
        /* Save SCOMPARE1 */
 
@@ -724,13 +727,14 @@ common_exception_exit:
        wsr     a3, sar
 
        /* Restore LBEG, LEND, LCOUNT */
-
+#if XCHAL_HAVE_LOOPS
        l32i    a2, a1, PT_LBEG
        l32i    a3, a1, PT_LEND
        wsr     a2, lbeg
        l32i    a2, a1, PT_LCOUNT
        wsr     a3, lend
        wsr     a2, lcount
+#endif
 
        /* We control single stepping through the ICOUNTLEVEL register. */
 
index 15a461e2a0edda4444bcfbad3046c270d5a599b1..9ed55649ac8ef1d8e6befae8f5d50498f6f5f35b 100644 (file)
@@ -249,7 +249,7 @@ ENTRY(_startup)
 
        __loopt a2, a3, a4, 2
        s32i    a0, a2, 0
-       __endla a2, a4, 4
+       __endla a2, a3, 4
 
 #if XCHAL_DCACHE_IS_WRITEBACK
 
index ace1892a875ea6505c12924474536586e894ef49..7ea4dd68893e2af1c63bb48fe03353181297673c 100644 (file)
@@ -222,8 +222,8 @@ __xtensa_copy_user:
        loopnez a7, .Loop2done
 #else /* !XCHAL_HAVE_LOOPS */
        beqz    a7, .Loop2done
-       slli    a10, a7, 4
-       add     a10, a10, a3    # a10 = end of last 16B source chunk
+       slli    a12, a7, 4
+       add     a12, a12, a3    # a12 = end of last 16B source chunk
 #endif /* !XCHAL_HAVE_LOOPS */
 .Loop2:
        EX(l32i, a7, a3,  4, l_fixup)
@@ -241,7 +241,7 @@ __xtensa_copy_user:
        EX(s32i, a9, a5, 12, s_fixup)
        addi    a5, a5, 16
 #if !XCHAL_HAVE_LOOPS
-       blt     a3, a10, .Loop2
+       blt     a3, a12, .Loop2
 #endif /* !XCHAL_HAVE_LOOPS */
 .Loop2done:
        bbci.l  a4, 3, .L12
index da7d1824086697a5f98714b8151d0759695f912f..391820539f0ae12bea63f1327cf859357647c859 100644 (file)
@@ -61,7 +61,9 @@ void platform_restart(void)
 #if XCHAL_NUM_IBREAK > 0
                             "wsr       a2, ibreakenable\n\t"
 #endif
+#if XCHAL_HAVE_LOOPS
                             "wsr       a2, lcount\n\t"
+#endif
                             "movi      a2, 0x1f\n\t"
                             "wsr       a2, ps\n\t"
                             "isync\n\t"
index b90555cb80890135fee12f7cc3ec361127106836..87678961a8c87348e56556dd9b04ab3fa623de36 100644 (file)
@@ -72,7 +72,9 @@ void platform_restart(void)
 #if XCHAL_NUM_IBREAK > 0
                              "wsr      a2, ibreakenable\n\t"
 #endif
+#if XCHAL_HAVE_LOOPS
                              "wsr      a2, lcount\n\t"
+#endif
                              "movi     a2, 0x1f\n\t"
                              "wsr      a2, ps\n\t"
                              "isync\n\t"
index b4cf70e535ab54038e7ee960b14f46c8c5592738..e9f65f79cf2ea0bff6393313385bbebf500db9a3 100644 (file)
@@ -63,7 +63,9 @@ void platform_restart(void)
 #if XCHAL_NUM_IBREAK > 0
                              "wsr      a2, ibreakenable\n\t"
 #endif
+#if XCHAL_HAVE_LOOPS
                              "wsr      a2, lcount\n\t"
+#endif
                              "movi     a2, 0x1f\n\t"
                              "wsr      a2, ps\n\t"
                              "isync\n\t"