1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 29d42c84fSVineet Gupta/* 36d1a20b1SVineet Gupta * Common Low Level Interrupts/Traps/Exceptions(non-TLB) Handling for ARC 46d1a20b1SVineet Gupta * (included from entry-<isa>.S 59d42c84fSVineet Gupta * 66d1a20b1SVineet Gupta * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) 79d42c84fSVineet Gupta * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 89d42c84fSVineet Gupta */ 99d42c84fSVineet Gupta 109d42c84fSVineet Gupta/*------------------------------------------------------------------ 119d42c84fSVineet Gupta * Function ABI 129d42c84fSVineet Gupta *------------------------------------------------------------------ 139d42c84fSVineet Gupta * 149d42c84fSVineet Gupta * Arguments r0 - r7 159d42c84fSVineet Gupta * Caller Saved Registers r0 - r12 169d42c84fSVineet Gupta * Callee Saved Registers r13- r25 179d42c84fSVineet Gupta * Global Pointer (gp) r26 189d42c84fSVineet Gupta * Frame Pointer (fp) r27 199d42c84fSVineet Gupta * Stack Pointer (sp) r28 209d42c84fSVineet Gupta * Branch link register (blink) r31 219d42c84fSVineet Gupta *------------------------------------------------------------------ 229d42c84fSVineet Gupta */ 239d42c84fSVineet Gupta 24c7e6d792SVineet Gupta;################### Special Sys Call Wrappers ########################## 25c7e6d792SVineet Gupta 26c7e6d792SVineet GuptaENTRY(sys_clone_wrapper) 27c7e6d792SVineet Gupta SAVE_CALLEE_SAVED_USER 28c7e6d792SVineet Gupta bl @sys_clone 29c7e6d792SVineet Gupta DISCARD_CALLEE_SAVED_USER 30c7e6d792SVineet Gupta 31c7e6d792SVineet Gupta GET_CURR_THR_INFO_FLAGS r10 32fb0b5490SSergey Matyukevich and.f 0, r10, _TIF_SYSCALL_WORK 33c7e6d792SVineet Gupta bnz tracesys_exit 34c7e6d792SVineet Gupta 352dad1122SVineet Gupta b .Lret_from_system_call 36c7e6d792SVineet GuptaEND(sys_clone_wrapper) 37c7e6d792SVineet Gupta 38bd71c453SVineet GuptaENTRY(sys_clone3_wrapper) 39bd71c453SVineet Gupta SAVE_CALLEE_SAVED_USER 40bd71c453SVineet Gupta bl @sys_clone3 41bd71c453SVineet Gupta DISCARD_CALLEE_SAVED_USER 42bd71c453SVineet Gupta 43bd71c453SVineet Gupta GET_CURR_THR_INFO_FLAGS r10 44fb0b5490SSergey Matyukevich and.f 0, r10, _TIF_SYSCALL_WORK 45bd71c453SVineet Gupta bnz tracesys_exit 46bd71c453SVineet Gupta 47bd71c453SVineet Gupta b .Lret_from_system_call 48bd71c453SVineet GuptaEND(sys_clone3_wrapper) 49bd71c453SVineet Gupta 50c7e6d792SVineet GuptaENTRY(ret_from_fork) 51c7e6d792SVineet Gupta ; when the forked child comes here from the __switch_to function 52c7e6d792SVineet Gupta ; r0 has the last task pointer. 53c7e6d792SVineet Gupta ; put last task in scheduler queue 546de6066cSYuriy Kolerov jl @schedule_tail 55c7e6d792SVineet Gupta 56c7e6d792SVineet Gupta ld r9, [sp, PT_status32] 57c7e6d792SVineet Gupta brne r9, 0, 1f 58c7e6d792SVineet Gupta 59c7e6d792SVineet Gupta jl.d [r14] ; kernel thread entry point 60c7e6d792SVineet Gupta mov r0, r13 ; (see PF_KTHREAD block in copy_thread) 61c7e6d792SVineet Gupta 62c7e6d792SVineet Gupta1: 63c7e6d792SVineet Gupta ; Return to user space 64c7e6d792SVineet Gupta ; 1. Any forked task (Reach here via BRne above) 65c7e6d792SVineet Gupta ; 2. First ever init task (Reach here via return from JL above) 66c7e6d792SVineet Gupta ; This is the historic "kernel_execve" use-case, to return to init 67c7e6d792SVineet Gupta ; user mode, in a round about way since that is always done from 68c7e6d792SVineet Gupta ; a kernel thread which is executed via JL above but always returns 69c7e6d792SVineet Gupta ; out whenever kernel_execve (now inline do_fork()) is involved 70c7e6d792SVineet Gupta b ret_from_exception 71c7e6d792SVineet GuptaEND(ret_from_fork) 72c7e6d792SVineet Gupta 739d42c84fSVineet Gupta;################### Non TLB Exception Handling ############################# 749d42c84fSVineet Gupta 759d42c84fSVineet Gupta; --------------------------------------------- 769d42c84fSVineet Gupta; Instruction Error Exception Handler 779d42c84fSVineet Gupta; --------------------------------------------- 789d42c84fSVineet Gupta 79ec7ac6afSVineet GuptaENTRY(instr_service) 809d42c84fSVineet Gupta 8137f3ac49SVineet Gupta EXCEPTION_PROLOGUE 829d42c84fSVineet Gupta 839d42c84fSVineet Gupta bl do_insterror_or_kprobe 849d42c84fSVineet Gupta b ret_from_exception 85ec7ac6afSVineet GuptaEND(instr_service) 869d42c84fSVineet Gupta 879d42c84fSVineet Gupta; --------------------------------------------- 889d42c84fSVineet Gupta; Machine Check Exception Handler 899d42c84fSVineet Gupta; --------------------------------------------- 909d42c84fSVineet Gupta 91ec7ac6afSVineet GuptaENTRY(EV_MachineCheck) 929d42c84fSVineet Gupta 9313347c10SVineet Gupta EXCEPTION_PROLOGUE_KEEP_AE ; ECR returned in r10 949d42c84fSVineet Gupta 9538a9ff6dSVineet Gupta lr r0, [efa] 9638a9ff6dSVineet Gupta mov r1, sp 979d42c84fSVineet Gupta 98*ebfc2fd8SBjorn Helgaas ; MC exceptions disable MMU 99a79a9c76SVineet Gupta ARC_MMU_REENABLE r3 1001ee55a8fSJose Abreu 1010e93ecaeSVineet Gupta lsr r3, r10, 8 1021898a959SVineet Gupta bmsk r3, r3, 7 1031898a959SVineet Gupta brne r3, ECR_C_MCHK_DUP_TLB, 1f 1041898a959SVineet Gupta 1059d42c84fSVineet Gupta bl do_tlb_overlap_fault 1069d42c84fSVineet Gupta b ret_from_exception 1079d42c84fSVineet Gupta 1089d42c84fSVineet Gupta1: 1099d42c84fSVineet Gupta ; DEAD END: can't do much, display Regs and HALT 1109d42c84fSVineet Gupta SAVE_CALLEE_SAVED_USER 1119d42c84fSVineet Gupta 1129d42c84fSVineet Gupta GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10 1139d42c84fSVineet Gupta st sp, [r10, THREAD_CALLEE_REG] 1149d42c84fSVineet Gupta 1159d42c84fSVineet Gupta j do_machine_check_fault 1169d42c84fSVineet Gupta 117ec7ac6afSVineet GuptaEND(EV_MachineCheck) 1189d42c84fSVineet Gupta 1199d42c84fSVineet Gupta; --------------------------------------------- 1209d42c84fSVineet Gupta; Privilege Violation Exception Handler 1219d42c84fSVineet Gupta; --------------------------------------------- 122ec7ac6afSVineet GuptaENTRY(EV_PrivilegeV) 1239d42c84fSVineet Gupta 12437f3ac49SVineet Gupta EXCEPTION_PROLOGUE 1259d42c84fSVineet Gupta 1269d42c84fSVineet Gupta bl do_privilege_fault 1279d42c84fSVineet Gupta b ret_from_exception 128ec7ac6afSVineet GuptaEND(EV_PrivilegeV) 1299d42c84fSVineet Gupta 1309d42c84fSVineet Gupta; --------------------------------------------- 1319d42c84fSVineet Gupta; Extension Instruction Exception Handler 1329d42c84fSVineet Gupta; --------------------------------------------- 133ec7ac6afSVineet GuptaENTRY(EV_Extension) 1349d42c84fSVineet Gupta 13537f3ac49SVineet Gupta EXCEPTION_PROLOGUE 1369d42c84fSVineet Gupta 1379d42c84fSVineet Gupta bl do_extension_fault 1389d42c84fSVineet Gupta b ret_from_exception 139ec7ac6afSVineet GuptaEND(EV_Extension) 1409d42c84fSVineet Gupta 1414bf4564bSVineet Gupta;################ Trap Handling (Syscall, Breakpoint) ################## 142547f1125SVineet Gupta 1434bf4564bSVineet Gupta; --------------------------------------------- 1444bf4564bSVineet Gupta; syscall Tracing 1454bf4564bSVineet Gupta; --------------------------------------------- 146547f1125SVineet Guptatracesys: 147c505b0daSVineet Gupta ; safekeep EFA (r12) if syscall tracer wanted PC 148c505b0daSVineet Gupta ; for traps, ERET is pre-commit so points to next-PC 149547f1125SVineet Gupta GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11 150367f3fcdSVineet Gupta st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address 151547f1125SVineet Gupta 152c505b0daSVineet Gupta ; PRE syscall trace hook 153c505b0daSVineet Gupta mov r0, sp ; pt_regs 154c505b0daSVineet Gupta bl @syscall_trace_enter 155547f1125SVineet Gupta 156547f1125SVineet Gupta ; Tracing code now returns the syscall num (orig or modif) 157547f1125SVineet Gupta mov r8, r0 158547f1125SVineet Gupta 159547f1125SVineet Gupta ; Do the Sys Call as we normally would. 1603433adc8SVineet Gupta cmp r8, NR_syscalls - 1 161547f1125SVineet Gupta mov.hi r0, -ENOSYS 162547f1125SVineet Gupta bhi tracesys_exit 163547f1125SVineet Gupta 164547f1125SVineet Gupta ; Restore the sys-call args. Mere invocation of the hook abv could have 165547f1125SVineet Gupta ; clobbered them (since they are in scratch regs). The tracer could also 166547f1125SVineet Gupta ; have deliberately changed the syscall args: r0-r7 167547f1125SVineet Gupta ld r0, [sp, PT_r0] 168547f1125SVineet Gupta ld r1, [sp, PT_r1] 169547f1125SVineet Gupta ld r2, [sp, PT_r2] 170547f1125SVineet Gupta ld r3, [sp, PT_r3] 171547f1125SVineet Gupta ld r4, [sp, PT_r4] 172547f1125SVineet Gupta ld r5, [sp, PT_r5] 173547f1125SVineet Gupta ld r6, [sp, PT_r6] 174547f1125SVineet Gupta ld r7, [sp, PT_r7] 175547f1125SVineet Gupta ld.as r9, [sys_call_table, r8] 176c505b0daSVineet Gupta jl [r9] 177547f1125SVineet Gupta 178547f1125SVineet Guptatracesys_exit: 179c505b0daSVineet Gupta st r0, [sp, PT_r0] 180547f1125SVineet Gupta 181c505b0daSVineet Gupta ; POST syscall trace hook 182b1c6ecfdSSergey Matyukevich mov r0, sp ; pt_regs needed 183547f1125SVineet Gupta bl @syscall_trace_exit 184c505b0daSVineet Gupta 185c505b0daSVineet Gupta ; don't call ret_from_system_call as it saves r0, already done above 186c505b0daSVineet Gupta b ret_from_exception 187547f1125SVineet Gupta 1884bf4564bSVineet Gupta; --------------------------------------------- 1894bf4564bSVineet Gupta; Breakpoint TRAP 1904bf4564bSVineet Gupta; --------------------------------------------- 1919d42c84fSVineet Guptatrap_with_param: 19200fdec98SVineet Gupta mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc 193c505b0daSVineet Gupta mov r1, sp ; pt_regs 1949d42c84fSVineet Gupta 195c505b0daSVineet Gupta ; save callee regs in case tracer/gdb wants to peek 1969d42c84fSVineet Gupta SAVE_CALLEE_SAVED_USER 1979d42c84fSVineet Gupta 198c505b0daSVineet Gupta ; safekeep ref to callee regs 1999d42c84fSVineet Gupta GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10 2009d42c84fSVineet Gupta st sp, [r10, THREAD_CALLEE_REG] 2019d42c84fSVineet Gupta 202c505b0daSVineet Gupta ; call the non syscall trap handler 2039d42c84fSVineet Gupta bl do_non_swi_trap 2049d42c84fSVineet Gupta 205c505b0daSVineet Gupta ; unwind stack to discard callee regs 2069d42c84fSVineet Gupta DISCARD_CALLEE_SAVED_USER 2079d42c84fSVineet Gupta 2089d42c84fSVineet Gupta b ret_from_exception 2099d42c84fSVineet Gupta 2104bf4564bSVineet Gupta; --------------------------------------------- 2114bf4564bSVineet Gupta; syscall TRAP 2124bf4564bSVineet Gupta; ABI: (r0-r7) up to 8 args, (r8) syscall number 2134bf4564bSVineet Gupta; --------------------------------------------- 2149d42c84fSVineet Gupta 215ec7ac6afSVineet GuptaENTRY(EV_Trap) 2169d42c84fSVineet Gupta 21713347c10SVineet Gupta EXCEPTION_PROLOGUE_KEEP_AE 2189d42c84fSVineet Gupta 21900fdec98SVineet Gupta lr r12, [efa] 22000fdec98SVineet Gupta 22100fdec98SVineet Gupta FAKE_RET_FROM_EXCPN 22200fdec98SVineet Gupta 223c505b0daSVineet Gupta ;============ TRAP N : breakpoints, kprobes etc 22468e5c6f0SVineet Gupta bmsk.f 0, r10, 7 2259d42c84fSVineet Gupta bnz trap_with_param 2269d42c84fSVineet Gupta 227c505b0daSVineet Gupta ;============ TRAP 0 (no param): syscall 2289d42c84fSVineet Gupta 229c505b0daSVineet Gupta ; syscall tracing ongoing, invoke pre-post-hooks around syscall 230547f1125SVineet Gupta GET_CURR_THR_INFO_FLAGS r10 231fb0b5490SSergey Matyukevich and.f 0, r10, _TIF_SYSCALL_WORK 232547f1125SVineet Gupta bnz tracesys ; this never comes back 233547f1125SVineet Gupta 2344bf4564bSVineet Gupta ;============ Normal syscall case 2354bf4564bSVineet Gupta 2363433adc8SVineet Gupta cmp r8, NR_syscalls - 1 2379d42c84fSVineet Gupta mov.hi r0, -ENOSYS 2382dad1122SVineet Gupta bhi .Lret_from_system_call 2399d42c84fSVineet Gupta 2409d42c84fSVineet Gupta ld.as r9,[sys_call_table, r8] 241c505b0daSVineet Gupta jl [r9] 2429d42c84fSVineet Gupta 2432dad1122SVineet Gupta.Lret_from_system_call: 2449d42c84fSVineet Gupta st r0, [sp, PT_r0] ; sys call return value in pt_regs 2459d42c84fSVineet Gupta 2462dad1122SVineet Gupta ; fall through to ret_from_exception 2472dad1122SVineet GuptaEND(EV_Trap) 2489d42c84fSVineet Gupta 2499d42c84fSVineet Gupta;############# Return from Intr/Excp/Trap (Linux Specifics) ############## 2509d42c84fSVineet Gupta; 2519d42c84fSVineet Gupta; If ret to user mode do we need to handle signals, schedule() et al. 2529d42c84fSVineet Gupta 253ec7ac6afSVineet GuptaENTRY(ret_from_exception) 2549d42c84fSVineet Gupta 2559d42c84fSVineet Gupta ; Pre-{IRQ,Trap,Exception} K/U mode from pt_regs->status32 2569d42c84fSVineet Gupta ld r8, [sp, PT_status32] ; returning to User/Kernel Mode 2579d42c84fSVineet Gupta 2589d42c84fSVineet Gupta bbit0 r8, STATUS_U_BIT, resume_kernel_mode 2599d42c84fSVineet Gupta 2609d42c84fSVineet Gupta ; Before returning to User mode check-for-and-complete any pending work 2619d42c84fSVineet Gupta ; such as rescheduling/signal-delivery etc. 2629d42c84fSVineet Guptaresume_user_mode_begin: 2639d42c84fSVineet Gupta 2649d42c84fSVineet Gupta ; Disable IRQs to ensures that chk for pending work itself is atomic 2659d42c84fSVineet Gupta ; (and we don't end up missing a NEED_RESCHED/SIGPENDING due to an 2669d42c84fSVineet Gupta ; interim IRQ). 2679d42c84fSVineet Gupta IRQ_DISABLE r10 2689d42c84fSVineet Gupta 2699d42c84fSVineet Gupta ; Fast Path return to user mode if no pending work 2709d42c84fSVineet Gupta GET_CURR_THR_INFO_FLAGS r9 2719d42c84fSVineet Gupta and.f 0, r9, _TIF_WORK_MASK 272c10d6969SVineet Gupta bz .Lrestore_regs 2739d42c84fSVineet Gupta 2749d42c84fSVineet Gupta ; --- (Slow Path #1) task preemption --- 2759d42c84fSVineet Gupta bbit0 r9, TIF_NEED_RESCHED, .Lchk_pend_signals 2769d42c84fSVineet Gupta mov blink, resume_user_mode_begin ; tail-call to U mode ret chks 2776de6066cSYuriy Kolerov j @schedule ; BTST+Bnz causes relo error in link 2789d42c84fSVineet Gupta 2799d42c84fSVineet Gupta.Lchk_pend_signals: 2809d42c84fSVineet Gupta IRQ_ENABLE r10 2819d42c84fSVineet Gupta 2829d42c84fSVineet Gupta ; --- (Slow Path #2) pending signal --- 2839d42c84fSVineet Gupta mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume() 2849d42c84fSVineet Gupta 2850dafafc3SVineet Gupta GET_CURR_THR_INFO_FLAGS r9 286bb12433bSVineet Gupta and.f 0, r9, _TIF_SIGPENDING|_TIF_NOTIFY_SIGNAL 28753855e12SJens Axboe bz .Lchk_notify_resume 2889d42c84fSVineet Gupta 289c3581039SVineet Gupta ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs 290c3581039SVineet Gupta ; in pt_reg since the "C" ABI (kernel code) will automatically 291c3581039SVineet Gupta ; save/restore callee-saved regs. 292c3581039SVineet Gupta ; 293c3581039SVineet Gupta ; However, here we need to explicitly save callee regs because 2949d42c84fSVineet Gupta ; (i) If this signal causes coredump - full regfile needed 2959d42c84fSVineet Gupta ; (ii) If signal is SIGTRAP/SIGSTOP, task is being traced thus 2969d42c84fSVineet Gupta ; tracer might call PEEKUSR(CALLEE reg) 2979d42c84fSVineet Gupta ; 2989d42c84fSVineet Gupta ; NOTE: SP will grow up by size of CALLEE Reg-File 299cfca4b5aSVineet Gupta SAVE_CALLEE_SAVED_USER 3009d42c84fSVineet Gupta 3019d42c84fSVineet Gupta ; save location of saved Callee Regs @ thread_struct->callee 3029d42c84fSVineet Gupta GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10 3039d42c84fSVineet Gupta st sp, [r10, THREAD_CALLEE_REG] 3049d42c84fSVineet Gupta 3059d42c84fSVineet Gupta bl @do_signal 3069d42c84fSVineet Gupta 307c3581039SVineet Gupta ; Ideally we want to discard the Callee reg above, however if this was 308c3581039SVineet Gupta ; a tracing signal, tracer could have done a POKEUSR(CALLEE reg) 309c3581039SVineet Gupta RESTORE_CALLEE_SAVED_USER 3109d42c84fSVineet Gupta 3119d42c84fSVineet Gupta b resume_user_mode_begin ; loop back to start of U mode ret 3129d42c84fSVineet Gupta 3139d42c84fSVineet Gupta ; --- (Slow Path #3) notify_resume --- 3149d42c84fSVineet Gupta.Lchk_notify_resume: 3159d42c84fSVineet Gupta btst r9, TIF_NOTIFY_RESUME 3169d42c84fSVineet Gupta blnz @do_notify_resume 3179d42c84fSVineet Gupta b resume_user_mode_begin ; unconditionally back to U mode ret chks 3189d42c84fSVineet Gupta ; for single exit point from this block 3199d42c84fSVineet Gupta 3209d42c84fSVineet Guptaresume_kernel_mode: 3219d42c84fSVineet Gupta 3228aa9e85aSVineet Gupta ; Disable Interrupts from this point on 32391659172SThomas Gleixner ; CONFIG_PREEMPTION: This is a must for preempt_schedule_irq() 32491659172SThomas Gleixner ; !CONFIG_PREEMPTION: To ensure restore_regs is intr safe 325fce16bc3SVineet Gupta IRQ_DISABLE r9 326fce16bc3SVineet Gupta 32791659172SThomas Gleixner#ifdef CONFIG_PREEMPTION 3288aa9e85aSVineet Gupta 3299d42c84fSVineet Gupta ; Can't preempt if preemption disabled 3309d42c84fSVineet Gupta GET_CURR_THR_INFO_FROM_SP r10 3319d42c84fSVineet Gupta ld r8, [r10, THREAD_INFO_PREEMPT_COUNT] 332c10d6969SVineet Gupta brne r8, 0, .Lrestore_regs 3339d42c84fSVineet Gupta 3349d42c84fSVineet Gupta ; check if this task's NEED_RESCHED flag set 3359d42c84fSVineet Gupta ld r9, [r10, THREAD_INFO_FLAGS] 336c10d6969SVineet Gupta bbit0 r9, TIF_NEED_RESCHED, .Lrestore_regs 3379d42c84fSVineet Gupta 3389d42c84fSVineet Gupta ; Invoke PREEMPTION 3396de6066cSYuriy Kolerov jl preempt_schedule_irq 3409d42c84fSVineet Gupta 3419d42c84fSVineet Gupta ; preempt_schedule_irq() always returns with IRQ disabled 3429d42c84fSVineet Gupta#endif 3439d42c84fSVineet Gupta 3446d1a20b1SVineet Gupta b .Lrestore_regs 3459d42c84fSVineet Gupta 346c7e6d792SVineet Gupta##### DONT ADD CODE HERE - .Lrestore_regs actually follows in entry-<isa>.S 347bf90e1eaSVineet Gupta 348