| .. | .. |
|---|
| 13 | 13 | */ |
|---|
| 14 | 14 | |
|---|
| 15 | 15 | #include <linux/linkage.h> |
|---|
| 16 | +#include <linux/pgtable.h> |
|---|
| 16 | 17 | #include <asm/asm-offsets.h> |
|---|
| 17 | 18 | #include <asm/asmmacro.h> |
|---|
| 18 | 19 | #include <asm/processor.h> |
|---|
| .. | .. |
|---|
| 22 | 23 | #include <asm/unistd.h> |
|---|
| 23 | 24 | #include <asm/ptrace.h> |
|---|
| 24 | 25 | #include <asm/current.h> |
|---|
| 25 | | -#include <asm/pgtable.h> |
|---|
| 26 | 26 | #include <asm/page.h> |
|---|
| 27 | 27 | #include <asm/signal.h> |
|---|
| 28 | 28 | #include <asm/tlbflush.h> |
|---|
| .. | .. |
|---|
| 364 | 364 | s32i a2, a1, PT_DEBUGCAUSE |
|---|
| 365 | 365 | s32i a3, a1, PT_PC |
|---|
| 366 | 366 | |
|---|
| 367 | | - movi a2, -1 |
|---|
| 367 | + movi a2, NO_SYSCALL |
|---|
| 368 | 368 | rsr a3, excvaddr |
|---|
| 369 | 369 | s32i a2, a1, PT_SYSCALL |
|---|
| 370 | 370 | movi a2, 0 |
|---|
| .. | .. |
|---|
| 372 | 372 | #if XCHAL_HAVE_LOOPS |
|---|
| 373 | 373 | xsr a2, lcount |
|---|
| 374 | 374 | s32i a2, a1, PT_LCOUNT |
|---|
| 375 | +#endif |
|---|
| 376 | + |
|---|
| 377 | +#if XCHAL_HAVE_EXCLUSIVE |
|---|
| 378 | + /* Clear exclusive access monitor set by interrupted code */ |
|---|
| 379 | + clrex |
|---|
| 375 | 380 | #endif |
|---|
| 376 | 381 | |
|---|
| 377 | 382 | /* It is now save to restore the EXC_TABLE_FIXUP variable. */ |
|---|
| .. | .. |
|---|
| 414 | 419 | movi a3, LOCKLEVEL |
|---|
| 415 | 420 | |
|---|
| 416 | 421 | .Lexception: |
|---|
| 417 | | - movi a0, 1 << PS_WOE_BIT |
|---|
| 422 | + movi a0, PS_WOE_MASK |
|---|
| 418 | 423 | or a3, a3, a0 |
|---|
| 419 | 424 | #else |
|---|
| 420 | 425 | addi a2, a2, -EXCCAUSE_LEVEL1_INTERRUPT |
|---|
| .. | .. |
|---|
| 422 | 427 | extui a3, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH |
|---|
| 423 | 428 | # a3 = PS.INTLEVEL |
|---|
| 424 | 429 | moveqz a3, a0, a2 # a3 = LOCKLEVEL iff interrupt |
|---|
| 425 | | - movi a2, 1 << PS_WOE_BIT |
|---|
| 430 | + movi a2, PS_WOE_MASK |
|---|
| 426 | 431 | or a3, a3, a2 |
|---|
| 427 | 432 | rsr a2, exccause |
|---|
| 428 | 433 | #endif |
|---|
| .. | .. |
|---|
| 495 | 500 | */ |
|---|
| 496 | 501 | |
|---|
| 497 | 502 | _bbsi.l a4, TIF_NEED_RESCHED, 3f |
|---|
| 498 | | - _bbsi.l a4, TIF_NOTIFY_RESUME, 2f |
|---|
| 499 | | - _bbci.l a4, TIF_SIGPENDING, 5f |
|---|
| 503 | + movi a2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL |
|---|
| 504 | + bnone a4, a2, 5f |
|---|
| 500 | 505 | |
|---|
| 501 | 506 | 2: l32i a4, a1, PT_DEPC |
|---|
| 502 | 507 | bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f |
|---|
| .. | .. |
|---|
| 520 | 525 | call4 schedule # void schedule (void) |
|---|
| 521 | 526 | j 1b |
|---|
| 522 | 527 | |
|---|
| 523 | | -#ifdef CONFIG_PREEMPT |
|---|
| 528 | +#ifdef CONFIG_PREEMPTION |
|---|
| 524 | 529 | 6: |
|---|
| 525 | 530 | _bbci.l a4, TIF_NEED_RESCHED, 4f |
|---|
| 526 | 531 | |
|---|
| .. | .. |
|---|
| 529 | 534 | l32i a4, a2, TI_PRE_COUNT |
|---|
| 530 | 535 | bnez a4, 4f |
|---|
| 531 | 536 | call4 preempt_schedule_irq |
|---|
| 532 | | - j 1b |
|---|
| 537 | + j 4f |
|---|
| 533 | 538 | #endif |
|---|
| 534 | 539 | |
|---|
| 535 | 540 | #if XTENSA_FAKE_NMI |
|---|
| .. | .. |
|---|
| 922 | 927 | wsr a1, windowbase |
|---|
| 923 | 928 | rsync |
|---|
| 924 | 929 | |
|---|
| 925 | | - movi a1, (1 << PS_WOE_BIT) | LOCKLEVEL |
|---|
| 930 | + movi a1, PS_WOE_MASK | LOCKLEVEL |
|---|
| 926 | 931 | wsr a1, ps |
|---|
| 927 | 932 | rsync |
|---|
| 928 | 933 | |
|---|
| .. | .. |
|---|
| 938 | 943 | ENDPROC(unrecoverable_exception) |
|---|
| 939 | 944 | |
|---|
| 940 | 945 | /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */ |
|---|
| 946 | + |
|---|
| 947 | + __XTENSA_HANDLER |
|---|
| 948 | + .literal_position |
|---|
| 941 | 949 | |
|---|
| 942 | 950 | /* |
|---|
| 943 | 951 | * Fast-handler for alloca exceptions |
|---|
| .. | .. |
|---|
| 956 | 964 | * of the proper size instead. |
|---|
| 957 | 965 | * |
|---|
| 958 | 966 | * This algorithm simply backs out the register changes started by the user |
|---|
| 959 | | - * excpetion handler, makes it appear that we have started a window underflow |
|---|
| 967 | + * exception handler, makes it appear that we have started a window underflow |
|---|
| 960 | 968 | * by rotating the window back and then setting the old window base (OWB) in |
|---|
| 961 | 969 | * the 'ps' register with the rolled back window base. The 'movsp' instruction |
|---|
| 962 | 970 | * will be re-executed and this time since the next window frames is in the |
|---|
| 963 | 971 | * active AR registers it won't cause an exception. |
|---|
| 964 | 972 | * |
|---|
| 965 | 973 | * If the WindowUnderflow code gets a TLB miss the page will get mapped |
|---|
| 966 | | - * the the partial windeowUnderflow will be handeled in the double exception |
|---|
| 974 | + * the partial WindowUnderflow will be handled in the double exception |
|---|
| 967 | 975 | * handler. |
|---|
| 968 | 976 | * |
|---|
| 969 | 977 | * Entry condition: |
|---|
| .. | .. |
|---|
| 1003 | 1011 | 4: j _WindowUnderflow4 |
|---|
| 1004 | 1012 | ENDPROC(fast_alloca) |
|---|
| 1005 | 1013 | |
|---|
| 1014 | +#ifdef CONFIG_USER_ABI_CALL0_PROBE |
|---|
| 1006 | 1015 | /* |
|---|
| 1016 | + * fast illegal instruction handler. |
|---|
| 1017 | + * |
|---|
| 1018 | + * This is used to fix up user PS.WOE on the exception caused |
|---|
| 1019 | + * by the first opcode related to register window. If PS.WOE is |
|---|
| 1020 | + * already set it goes directly to the common user exception handler. |
|---|
| 1021 | + * |
|---|
| 1022 | + * Entry condition: |
|---|
| 1023 | + * |
|---|
| 1024 | + * a0: trashed, original value saved on stack (PT_AREG0) |
|---|
| 1025 | + * a1: a1 |
|---|
| 1026 | + * a2: new stack pointer, original in DEPC |
|---|
| 1027 | + * a3: a3 |
|---|
| 1028 | + * depc: a2, original value saved on stack (PT_DEPC) |
|---|
| 1029 | + * excsave_1: dispatch table |
|---|
| 1030 | + */ |
|---|
| 1031 | + |
|---|
| 1032 | +ENTRY(fast_illegal_instruction_user) |
|---|
| 1033 | + |
|---|
| 1034 | + rsr a0, ps |
|---|
| 1035 | + bbsi.l a0, PS_WOE_BIT, 1f |
|---|
| 1036 | + s32i a3, a2, PT_AREG3 |
|---|
| 1037 | + movi a3, PS_WOE_MASK |
|---|
| 1038 | + or a0, a0, a3 |
|---|
| 1039 | + wsr a0, ps |
|---|
| 1040 | + l32i a3, a2, PT_AREG3 |
|---|
| 1041 | + l32i a0, a2, PT_AREG0 |
|---|
| 1042 | + rsr a2, depc |
|---|
| 1043 | + rfe |
|---|
| 1044 | +1: |
|---|
| 1045 | + call0 user_exception |
|---|
| 1046 | + |
|---|
| 1047 | +ENDPROC(fast_illegal_instruction_user) |
|---|
| 1048 | +#endif |
|---|
| 1049 | + |
|---|
| 1050 | + /* |
|---|
| 1007 | 1051 | * fast system calls. |
|---|
| 1008 | 1052 | * |
|---|
| 1009 | 1053 | * WARNING: The kernel doesn't save the entire user context before |
|---|
| .. | .. |
|---|
| 1022 | 1066 | * excsave_1: dispatch table |
|---|
| 1023 | 1067 | */ |
|---|
| 1024 | 1068 | |
|---|
| 1025 | | -ENTRY(fast_syscall_kernel) |
|---|
| 1026 | | - |
|---|
| 1027 | | - /* Skip syscall. */ |
|---|
| 1028 | | - |
|---|
| 1029 | | - rsr a0, epc1 |
|---|
| 1030 | | - addi a0, a0, 3 |
|---|
| 1031 | | - wsr a0, epc1 |
|---|
| 1032 | | - |
|---|
| 1033 | | - l32i a0, a2, PT_DEPC |
|---|
| 1034 | | - bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_syscall_unrecoverable |
|---|
| 1035 | | - |
|---|
| 1036 | | - rsr a0, depc # get syscall-nr |
|---|
| 1037 | | - _beqz a0, fast_syscall_spill_registers |
|---|
| 1038 | | - _beqi a0, __NR_xtensa, fast_syscall_xtensa |
|---|
| 1039 | | - |
|---|
| 1040 | | - j kernel_exception |
|---|
| 1041 | | - |
|---|
| 1042 | | -ENDPROC(fast_syscall_kernel) |
|---|
| 1043 | | - |
|---|
| 1044 | 1069 | ENTRY(fast_syscall_user) |
|---|
| 1045 | 1070 | |
|---|
| 1046 | 1071 | /* Skip syscall. */ |
|---|
| .. | .. |
|---|
| 1056 | 1081 | _beqz a0, fast_syscall_spill_registers |
|---|
| 1057 | 1082 | _beqi a0, __NR_xtensa, fast_syscall_xtensa |
|---|
| 1058 | 1083 | |
|---|
| 1059 | | - j user_exception |
|---|
| 1084 | + call0 user_exception |
|---|
| 1060 | 1085 | |
|---|
| 1061 | 1086 | ENDPROC(fast_syscall_user) |
|---|
| 1062 | 1087 | |
|---|
| .. | .. |
|---|
| 1378 | 1403 | rsr a3, excsave1 |
|---|
| 1379 | 1404 | l32i a1, a3, EXC_TABLE_KSTK |
|---|
| 1380 | 1405 | |
|---|
| 1381 | | - movi a4, (1 << PS_WOE_BIT) | LOCKLEVEL |
|---|
| 1406 | + movi a4, PS_WOE_MASK | LOCKLEVEL |
|---|
| 1382 | 1407 | wsr a4, ps |
|---|
| 1383 | 1408 | rsync |
|---|
| 1384 | 1409 | |
|---|
| .. | .. |
|---|
| 1747 | 1772 | |
|---|
| 1748 | 1773 | rsr a2, ps |
|---|
| 1749 | 1774 | bbsi.l a2, PS_UM_BIT, 1f |
|---|
| 1750 | | - j _kernel_exception |
|---|
| 1751 | | -1: j _user_exception |
|---|
| 1775 | + call0 _kernel_exception |
|---|
| 1776 | +1: call0 _user_exception |
|---|
| 1752 | 1777 | |
|---|
| 1753 | 1778 | ENDPROC(fast_second_level_miss) |
|---|
| 1754 | 1779 | |
|---|
| .. | .. |
|---|
| 1844 | 1869 | |
|---|
| 1845 | 1870 | rsr a2, ps |
|---|
| 1846 | 1871 | bbsi.l a2, PS_UM_BIT, 1f |
|---|
| 1847 | | - j _kernel_exception |
|---|
| 1848 | | -1: j _user_exception |
|---|
| 1872 | + call0 _kernel_exception |
|---|
| 1873 | +1: call0 _user_exception |
|---|
| 1849 | 1874 | |
|---|
| 1850 | 1875 | ENDPROC(fast_store_prohibited) |
|---|
| 1851 | 1876 | |
|---|
| 1852 | 1877 | #endif /* CONFIG_MMU */ |
|---|
| 1853 | 1878 | |
|---|
| 1879 | + .text |
|---|
| 1854 | 1880 | /* |
|---|
| 1855 | 1881 | * System Calls. |
|---|
| 1856 | 1882 | * |
|---|
| .. | .. |
|---|
| 1861 | 1887 | |
|---|
| 1862 | 1888 | ENTRY(system_call) |
|---|
| 1863 | 1889 | |
|---|
| 1864 | | - entry a1, 32 |
|---|
| 1890 | + abi_entry_default |
|---|
| 1865 | 1891 | |
|---|
| 1866 | 1892 | /* regs->syscall = regs->areg[2] */ |
|---|
| 1867 | 1893 | |
|---|
| 1868 | | - l32i a3, a2, PT_AREG2 |
|---|
| 1869 | | - mov a6, a2 |
|---|
| 1870 | | - s32i a3, a2, PT_SYSCALL |
|---|
| 1871 | | - call4 do_syscall_trace_enter |
|---|
| 1872 | | - mov a3, a6 |
|---|
| 1894 | + l32i a7, a2, PT_AREG2 |
|---|
| 1895 | + s32i a7, a2, PT_SYSCALL |
|---|
| 1873 | 1896 | |
|---|
| 1897 | + GET_THREAD_INFO(a4, a1) |
|---|
| 1898 | + l32i a3, a4, TI_FLAGS |
|---|
| 1899 | + movi a4, _TIF_WORK_MASK |
|---|
| 1900 | + and a3, a3, a4 |
|---|
| 1901 | + beqz a3, 1f |
|---|
| 1902 | + |
|---|
| 1903 | + mov a6, a2 |
|---|
| 1904 | + call4 do_syscall_trace_enter |
|---|
| 1905 | + beqz a6, .Lsyscall_exit |
|---|
| 1906 | + l32i a7, a2, PT_SYSCALL |
|---|
| 1907 | + |
|---|
| 1908 | +1: |
|---|
| 1874 | 1909 | /* syscall = sys_call_table[syscall_nr] */ |
|---|
| 1875 | 1910 | |
|---|
| 1876 | 1911 | movi a4, sys_call_table |
|---|
| 1877 | | - movi a5, __NR_syscall_count |
|---|
| 1912 | + movi a5, __NR_syscalls |
|---|
| 1878 | 1913 | movi a6, -ENOSYS |
|---|
| 1879 | | - bgeu a3, a5, 1f |
|---|
| 1914 | + bgeu a7, a5, 1f |
|---|
| 1880 | 1915 | |
|---|
| 1881 | | - addx4 a4, a3, a4 |
|---|
| 1916 | + addx4 a4, a7, a4 |
|---|
| 1882 | 1917 | l32i a4, a4, 0 |
|---|
| 1883 | | - movi a5, sys_ni_syscall; |
|---|
| 1884 | | - beq a4, a5, 1f |
|---|
| 1885 | 1918 | |
|---|
| 1886 | 1919 | /* Load args: arg0 - arg5 are passed via regs. */ |
|---|
| 1887 | 1920 | |
|---|
| .. | .. |
|---|
| 1892 | 1925 | l32i a10, a2, PT_AREG8 |
|---|
| 1893 | 1926 | l32i a11, a2, PT_AREG9 |
|---|
| 1894 | 1927 | |
|---|
| 1895 | | - /* Pass one additional argument to the syscall: pt_regs (on stack) */ |
|---|
| 1896 | | - s32i a2, a1, 0 |
|---|
| 1897 | | - |
|---|
| 1898 | 1928 | callx4 a4 |
|---|
| 1899 | 1929 | |
|---|
| 1900 | 1930 | 1: /* regs->areg[2] = return_value */ |
|---|
| 1901 | 1931 | |
|---|
| 1902 | 1932 | s32i a6, a2, PT_AREG2 |
|---|
| 1933 | + bnez a3, 1f |
|---|
| 1934 | +.Lsyscall_exit: |
|---|
| 1935 | + abi_ret_default |
|---|
| 1936 | + |
|---|
| 1937 | +1: |
|---|
| 1903 | 1938 | mov a6, a2 |
|---|
| 1904 | 1939 | call4 do_syscall_trace_leave |
|---|
| 1905 | | - retw |
|---|
| 1940 | + abi_ret_default |
|---|
| 1906 | 1941 | |
|---|
| 1907 | 1942 | ENDPROC(system_call) |
|---|
| 1908 | 1943 | |
|---|
| .. | .. |
|---|
| 1953 | 1988 | |
|---|
| 1954 | 1989 | ENTRY(_switch_to) |
|---|
| 1955 | 1990 | |
|---|
| 1956 | | - entry a1, 48 |
|---|
| 1991 | + abi_entry(XTENSA_SPILL_STACK_RESERVE) |
|---|
| 1957 | 1992 | |
|---|
| 1958 | 1993 | mov a11, a3 # and 'next' (a3) |
|---|
| 1959 | 1994 | |
|---|
| .. | .. |
|---|
| 1990 | 2025 | s32i a3, a4, THREAD_CPENABLE |
|---|
| 1991 | 2026 | #endif |
|---|
| 1992 | 2027 | |
|---|
| 2028 | +#if XCHAL_HAVE_EXCLUSIVE |
|---|
| 2029 | + l32i a3, a5, THREAD_ATOMCTL8 |
|---|
| 2030 | + getex a3 |
|---|
| 2031 | + s32i a3, a4, THREAD_ATOMCTL8 |
|---|
| 2032 | +#endif |
|---|
| 2033 | + |
|---|
| 1993 | 2034 | /* Flush register file. */ |
|---|
| 1994 | 2035 | |
|---|
| 1995 | 2036 | spill_registers_kernel |
|---|
| .. | .. |
|---|
| 2014 | 2055 | wsr a14, ps |
|---|
| 2015 | 2056 | rsync |
|---|
| 2016 | 2057 | |
|---|
| 2017 | | - retw |
|---|
| 2058 | + abi_ret(XTENSA_SPILL_STACK_RESERVE) |
|---|
| 2018 | 2059 | |
|---|
| 2019 | 2060 | ENDPROC(_switch_to) |
|---|
| 2020 | 2061 | |
|---|