.. | .. |
---|
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 | |
---|