Commit 84e3da3b authored by Max Filippov's avatar Max Filippov Committed by Luis Henriques

xtensa: fixes for configs without loop option

commit 5029615e upstream.

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.
Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 214fcf79
...@@ -35,9 +35,10 @@ ...@@ -35,9 +35,10 @@
* __loop as * __loop as
* restart loop. 'as' register must not have been modified! * restart loop. 'as' register must not have been modified!
* *
* __endla ar, at, incr * __endla ar, as, incr
* ar start address (modified) * 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 * inc increment
*/ */
...@@ -97,7 +98,7 @@ ...@@ -97,7 +98,7 @@
.endm .endm
/* /*
* loop from ar to ax * loop from ar to as
*/ */
.macro __loopt ar, as, at, incr_log2 .macro __loopt ar, as, at, incr_log2
......
...@@ -335,8 +335,10 @@ common_exception: ...@@ -335,8 +335,10 @@ common_exception:
s32i a2, a1, PT_SYSCALL s32i a2, a1, PT_SYSCALL
movi a2, 0 movi a2, 0
s32i a3, a1, PT_EXCVADDR s32i a3, a1, PT_EXCVADDR
#if XCHAL_HAVE_LOOPS
xsr a2, lcount xsr a2, lcount
s32i a2, a1, PT_LCOUNT s32i a2, a1, PT_LCOUNT
#endif
/* It is now save to restore the EXC_TABLE_FIXUP variable. */ /* It is now save to restore the EXC_TABLE_FIXUP variable. */
...@@ -368,11 +370,12 @@ common_exception: ...@@ -368,11 +370,12 @@ common_exception:
s32i a3, a1, PT_PS # save ps s32i a3, a1, PT_PS # save ps
/* Save lbeg, lend */ /* Save lbeg, lend */
#if XCHAL_HAVE_LOOPS
rsr a2, lbeg rsr a2, lbeg
rsr a3, lend rsr a3, lend
s32i a2, a1, PT_LBEG s32i a2, a1, PT_LBEG
s32i a3, a1, PT_LEND s32i a3, a1, PT_LEND
#endif
/* Save SCOMPARE1 */ /* Save SCOMPARE1 */
...@@ -664,13 +667,14 @@ common_exception_exit: ...@@ -664,13 +667,14 @@ common_exception_exit:
wsr a3, sar wsr a3, sar
/* Restore LBEG, LEND, LCOUNT */ /* Restore LBEG, LEND, LCOUNT */
#if XCHAL_HAVE_LOOPS
l32i a2, a1, PT_LBEG l32i a2, a1, PT_LBEG
l32i a3, a1, PT_LEND l32i a3, a1, PT_LEND
wsr a2, lbeg wsr a2, lbeg
l32i a2, a1, PT_LCOUNT l32i a2, a1, PT_LCOUNT
wsr a3, lend wsr a3, lend
wsr a2, lcount wsr a2, lcount
#endif
/* We control single stepping through the ICOUNTLEVEL register. */ /* We control single stepping through the ICOUNTLEVEL register. */
......
...@@ -244,7 +244,7 @@ ENTRY(_startup) ...@@ -244,7 +244,7 @@ ENTRY(_startup)
__loopt a2, a3, a4, 2 __loopt a2, a3, a4, 2
s32i a0, a2, 0 s32i a0, a2, 0
__endla a2, a4, 4 __endla a2, a3, 4
#if XCHAL_DCACHE_IS_WRITEBACK #if XCHAL_DCACHE_IS_WRITEBACK
......
...@@ -222,8 +222,8 @@ __xtensa_copy_user: ...@@ -222,8 +222,8 @@ __xtensa_copy_user:
loopnez a7, .Loop2done loopnez a7, .Loop2done
#else /* !XCHAL_HAVE_LOOPS */ #else /* !XCHAL_HAVE_LOOPS */
beqz a7, .Loop2done beqz a7, .Loop2done
slli a10, a7, 4 slli a12, a7, 4
add a10, a10, a3 # a10 = end of last 16B source chunk add a12, a12, a3 # a12 = end of last 16B source chunk
#endif /* !XCHAL_HAVE_LOOPS */ #endif /* !XCHAL_HAVE_LOOPS */
.Loop2: .Loop2:
EX(l32i, a7, a3, 4, l_fixup) EX(l32i, a7, a3, 4, l_fixup)
...@@ -241,7 +241,7 @@ __xtensa_copy_user: ...@@ -241,7 +241,7 @@ __xtensa_copy_user:
EX(s32i, a9, a5, 12, s_fixup) EX(s32i, a9, a5, 12, s_fixup)
addi a5, a5, 16 addi a5, a5, 16
#if !XCHAL_HAVE_LOOPS #if !XCHAL_HAVE_LOOPS
blt a3, a10, .Loop2 blt a3, a12, .Loop2
#endif /* !XCHAL_HAVE_LOOPS */ #endif /* !XCHAL_HAVE_LOOPS */
.Loop2done: .Loop2done:
bbci.l a4, 3, .L12 bbci.l a4, 3, .L12
......
...@@ -61,7 +61,9 @@ void platform_restart(void) ...@@ -61,7 +61,9 @@ void platform_restart(void)
#if XCHAL_NUM_IBREAK > 0 #if XCHAL_NUM_IBREAK > 0
"wsr a2, ibreakenable\n\t" "wsr a2, ibreakenable\n\t"
#endif #endif
#if XCHAL_HAVE_LOOPS
"wsr a2, lcount\n\t" "wsr a2, lcount\n\t"
#endif
"movi a2, 0x1f\n\t" "movi a2, 0x1f\n\t"
"wsr a2, ps\n\t" "wsr a2, ps\n\t"
"isync\n\t" "isync\n\t"
......
...@@ -72,7 +72,9 @@ void platform_restart(void) ...@@ -72,7 +72,9 @@ void platform_restart(void)
#if XCHAL_NUM_IBREAK > 0 #if XCHAL_NUM_IBREAK > 0
"wsr a2, ibreakenable\n\t" "wsr a2, ibreakenable\n\t"
#endif #endif
#if XCHAL_HAVE_LOOPS
"wsr a2, lcount\n\t" "wsr a2, lcount\n\t"
#endif
"movi a2, 0x1f\n\t" "movi a2, 0x1f\n\t"
"wsr a2, ps\n\t" "wsr a2, ps\n\t"
"isync\n\t" "isync\n\t"
......
...@@ -63,7 +63,9 @@ void platform_restart(void) ...@@ -63,7 +63,9 @@ void platform_restart(void)
#if XCHAL_NUM_IBREAK > 0 #if XCHAL_NUM_IBREAK > 0
"wsr a2, ibreakenable\n\t" "wsr a2, ibreakenable\n\t"
#endif #endif
#if XCHAL_HAVE_LOOPS
"wsr a2, lcount\n\t" "wsr a2, lcount\n\t"
#endif
"movi a2, 0x1f\n\t" "movi a2, 0x1f\n\t"
"wsr a2, ps\n\t" "wsr a2, ps\n\t"
"isync\n\t" "isync\n\t"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment