aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/xtensa/include/asm/traps.h44
-rw-r--r--arch/xtensa/kernel/entry.S60
2 files changed, 76 insertions, 28 deletions
diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h
index 8c194f6af45e..677bfcf4ee5d 100644
--- a/arch/xtensa/include/asm/traps.h
+++ b/arch/xtensa/include/asm/traps.h
@@ -23,25 +23,37 @@ void secondary_trap_init(void);
23 23
24static inline void spill_registers(void) 24static inline void spill_registers(void)
25{ 25{
26 26#if XCHAL_NUM_AREGS > 16
27 __asm__ __volatile__ ( 27 __asm__ __volatile__ (
28 "movi a14, "__stringify((1 << PS_EXCM_BIT) | LOCKLEVEL)"\n\t" 28 " call12 1f\n"
29 "mov a12, a0\n\t" 29 " _j 2f\n"
30 "rsr a13, sar\n\t" 30 " retw\n"
31 "xsr a14, ps\n\t" 31 " .align 4\n"
32 "movi a0, _spill_registers\n\t" 32 "1:\n"
33 "rsync\n\t" 33 " _entry a1, 48\n"
34 "callx0 a0\n\t" 34 " addi a12, a0, 3\n"
35 "mov a0, a12\n\t" 35#if XCHAL_NUM_AREGS > 32
36 "wsr a13, sar\n\t" 36 " .rept (" __stringify(XCHAL_NUM_AREGS) " - 32) / 12\n"
37 "wsr a14, ps\n\t" 37 " _entry a1, 48\n"
38 : : 38 " mov a12, a0\n"
39#if defined(CONFIG_FRAME_POINTER) 39 " .endr\n"
40 : "a2", "a3", "a4", "a11", "a12", "a13", "a14", "a15", 40#endif
41 " _entry a1, 48\n"
42#if XCHAL_NUM_AREGS % 12 == 0
43 " mov a8, a8\n"
44#elif XCHAL_NUM_AREGS % 12 == 4
45 " mov a12, a12\n"
46#elif XCHAL_NUM_AREGS % 12 == 8
47 " mov a4, a4\n"
48#endif
49 " retw\n"
50 "2:\n"
51 : : : "a12", "a13", "memory");
41#else 52#else
42 : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", 53 __asm__ __volatile__ (
54 " mov a12, a12\n"
55 : : : "memory");
43#endif 56#endif
44 "memory");
45} 57}
46 58
47#endif /* _XTENSA_TRAPS_H */ 59#endif /* _XTENSA_TRAPS_H */
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 21dbe6bdb8ed..0489918e40d2 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1794,6 +1794,43 @@ ENTRY(system_call)
1794 1794
1795ENDPROC(system_call) 1795ENDPROC(system_call)
1796 1796
1797/*
1798 * Spill live registers on the kernel stack macro.
1799 *
1800 * Entry condition: ps.woe is set, ps.excm is cleared
1801 * Exit condition: windowstart has single bit set
1802 * May clobber: a12, a13
1803 */
1804 .macro spill_registers_kernel
1805
1806#if XCHAL_NUM_AREGS > 16
1807 call12 1f
1808 _j 2f
1809 retw
1810 .align 4
18111:
1812 _entry a1, 48
1813 addi a12, a0, 3
1814#if XCHAL_NUM_AREGS > 32
1815 .rept (XCHAL_NUM_AREGS - 32) / 12
1816 _entry a1, 48
1817 mov a12, a0
1818 .endr
1819#endif
1820 _entry a1, 48
1821#if XCHAL_NUM_AREGS % 12 == 0
1822 mov a8, a8
1823#elif XCHAL_NUM_AREGS % 12 == 4
1824 mov a12, a12
1825#elif XCHAL_NUM_AREGS % 12 == 8
1826 mov a4, a4
1827#endif
1828 retw
18292:
1830#else
1831 mov a12, a12
1832#endif
1833 .endm
1797 1834
1798/* 1835/*
1799 * Task switch. 1836 * Task switch.
@@ -1806,21 +1843,20 @@ ENTRY(_switch_to)
1806 1843
1807 entry a1, 16 1844 entry a1, 16
1808 1845
1809 mov a12, a2 # preserve 'prev' (a2) 1846 mov a10, a2 # preserve 'prev' (a2)
1810 mov a13, a3 # and 'next' (a3) 1847 mov a11, a3 # and 'next' (a3)
1811 1848
1812 l32i a4, a2, TASK_THREAD_INFO 1849 l32i a4, a2, TASK_THREAD_INFO
1813 l32i a5, a3, TASK_THREAD_INFO 1850 l32i a5, a3, TASK_THREAD_INFO
1814 1851
1815 save_xtregs_user a4 a6 a8 a9 a10 a11 THREAD_XTREGS_USER 1852 save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
1816 1853
1817 s32i a0, a12, THREAD_RA # save return address 1854 s32i a0, a10, THREAD_RA # save return address
1818 s32i a1, a12, THREAD_SP # save stack pointer 1855 s32i a1, a10, THREAD_SP # save stack pointer
1819 1856
1820 /* Disable ints while we manipulate the stack pointer. */ 1857 /* Disable ints while we manipulate the stack pointer. */
1821 1858
1822 movi a14, (1 << PS_EXCM_BIT) | LOCKLEVEL 1859 rsil a14, LOCKLEVEL
1823 xsr a14, ps
1824 rsr a3, excsave1 1860 rsr a3, excsave1
1825 rsync 1861 rsync
1826 s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */ 1862 s32i a3, a3, EXC_TABLE_FIXUP /* enter critical section */
@@ -1835,7 +1871,7 @@ ENTRY(_switch_to)
1835 1871
1836 /* Flush register file. */ 1872 /* Flush register file. */
1837 1873
1838 call0 _spill_registers # destroys a3, a4, and SAR 1874 spill_registers_kernel
1839 1875
1840 /* Set kernel stack (and leave critical section) 1876 /* Set kernel stack (and leave critical section)
1841 * Note: It's save to set it here. The stack will not be overwritten 1877 * Note: It's save to set it here. The stack will not be overwritten
@@ -1851,13 +1887,13 @@ ENTRY(_switch_to)
1851 1887
1852 /* restore context of the task 'next' */ 1888 /* restore context of the task 'next' */
1853 1889
1854 l32i a0, a13, THREAD_RA # restore return address 1890 l32i a0, a11, THREAD_RA # restore return address
1855 l32i a1, a13, THREAD_SP # restore stack pointer 1891 l32i a1, a11, THREAD_SP # restore stack pointer
1856 1892
1857 load_xtregs_user a5 a6 a8 a9 a10 a11 THREAD_XTREGS_USER 1893 load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER
1858 1894
1859 wsr a14, ps 1895 wsr a14, ps
1860 mov a2, a12 # return 'prev' 1896 mov a2, a10 # return 'prev'
1861 rsync 1897 rsync
1862 1898
1863 retw 1899 retw