^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Common Low Level Interrupts/Traps/Exceptions(non-TLB) Handling for ARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * (included from entry-<isa>.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Function ABI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Arguments r0 - r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Caller Saved Registers r0 - r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Callee Saved Registers r13- r25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Global Pointer (gp) r26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Frame Pointer (fp) r27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Stack Pointer (sp) r28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Branch link register (blink) r31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) ;################### Special Sys Call Wrappers ##########################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ENTRY(sys_clone_wrapper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) SAVE_CALLEE_SAVED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) bl @sys_clone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) DISCARD_CALLEE_SAVED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) GET_CURR_THR_INFO_FLAGS r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) btst r10, TIF_SYSCALL_TRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) bnz tracesys_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) b .Lret_from_system_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) END(sys_clone_wrapper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ENTRY(sys_clone3_wrapper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) SAVE_CALLEE_SAVED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) bl @sys_clone3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) DISCARD_CALLEE_SAVED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) GET_CURR_THR_INFO_FLAGS r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) btst r10, TIF_SYSCALL_TRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) bnz tracesys_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) b .Lret_from_system_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) END(sys_clone3_wrapper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ENTRY(ret_from_fork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ; when the forked child comes here from the __switch_to function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ; r0 has the last task pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ; put last task in scheduler queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) jl @schedule_tail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ld r9, [sp, PT_status32]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) brne r9, 0, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) jl.d [r14] ; kernel thread entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mov r0, r13 ; (see PF_KTHREAD block in copy_thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ; Return to user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ; 1. Any forked task (Reach here via BRne above)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ; 2. First ever init task (Reach here via return from JL above)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ; This is the historic "kernel_execve" use-case, to return to init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ; user mode, in a round about way since that is always done from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ; a kernel thread which is executed via JL above but always returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ; out whenever kernel_execve (now inline do_fork()) is involved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) b ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) END(ret_from_fork)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ;################### Non TLB Exception Handling #############################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ; Instruction Error Exception Handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ENTRY(instr_service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) EXCEPTION_PROLOGUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) lr r0, [efa]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mov r1, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) FAKE_RET_FROM_EXCPN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) bl do_insterror_or_kprobe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) b ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) END(instr_service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ; Machine Check Exception Handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ENTRY(EV_MachineCheck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EXCEPTION_PROLOGUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) lr r2, [ecr]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) lr r0, [efa]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mov r1, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ; hardware auto-disables MMU, re-enable it to allow kernel vaddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ; access for say stack unwinding of modules for crash dumps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) lr r3, [ARC_REG_PID]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) or r3, r3, MMU_ENABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) sr r3, [ARC_REG_PID]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) lsr r3, r2, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) bmsk r3, r3, 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) brne r3, ECR_C_MCHK_DUP_TLB, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bl do_tlb_overlap_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) b ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ; DEAD END: can't do much, display Regs and HALT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) SAVE_CALLEE_SAVED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) st sp, [r10, THREAD_CALLEE_REG]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) j do_machine_check_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) END(EV_MachineCheck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ; Privilege Violation Exception Handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ENTRY(EV_PrivilegeV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) EXCEPTION_PROLOGUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) lr r0, [efa]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) mov r1, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) FAKE_RET_FROM_EXCPN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) bl do_privilege_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) b ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) END(EV_PrivilegeV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ; Extension Instruction Exception Handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ENTRY(EV_Extension)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) EXCEPTION_PROLOGUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) lr r0, [efa]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mov r1, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) FAKE_RET_FROM_EXCPN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) bl do_extension_fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) b ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) END(EV_Extension)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ;################ Trap Handling (Syscall, Breakpoint) ##################
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ; syscall Tracing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) tracesys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ; save EFA in case tracer wants the PC of traced task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ; using ERET won't work since next-PC has already committed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ; PRE Sys Call Ptrace hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mov r0, sp ; pt_regs needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) bl @syscall_trace_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ; Tracing code now returns the syscall num (orig or modif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mov r8, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ; Do the Sys Call as we normally would.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ; Validate the Sys Call number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) cmp r8, NR_syscalls - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mov.hi r0, -ENOSYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) bhi tracesys_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) ; Restore the sys-call args. Mere invocation of the hook abv could have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ; clobbered them (since they are in scratch regs). The tracer could also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ; have deliberately changed the syscall args: r0-r7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ld r0, [sp, PT_r0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ld r1, [sp, PT_r1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ld r2, [sp, PT_r2]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ld r3, [sp, PT_r3]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ld r4, [sp, PT_r4]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ld r5, [sp, PT_r5]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ld r6, [sp, PT_r6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ld r7, [sp, PT_r7]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ld.as r9, [sys_call_table, r8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) jl [r9] ; Entry into Sys Call Handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) tracesys_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) st r0, [sp, PT_r0] ; sys call return value in pt_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ;POST Sys Call Ptrace Hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) bl @syscall_trace_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) b ret_from_exception ; NOT ret_from_system_call at is saves r0 which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ; we'd done before calling post hook above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ; Breakpoint TRAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) trap_with_param:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) mov r1, sp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ; Save callee regs in case gdb wants to have a look
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ; SP will grow up by size of CALLEE Reg-File
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ; NOTE: clobbers r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) SAVE_CALLEE_SAVED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ; save location of saved Callee Regs @ thread_struct->pc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) st sp, [r10, THREAD_CALLEE_REG]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ; Call the trap handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) bl do_non_swi_trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ; unwind stack to discard Callee saved Regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) DISCARD_CALLEE_SAVED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) b ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ; syscall TRAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ; ABI: (r0-r7) upto 8 args, (r8) syscall number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ; ---------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ENTRY(EV_Trap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) EXCEPTION_PROLOGUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) lr r12, [efa]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) FAKE_RET_FROM_EXCPN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ;============ TRAP 1 :breakpoints
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ; Check ECR for trap with arg (PROLOGUE ensures r10 has ECR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) bmsk.f 0, r10, 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) bnz trap_with_param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ;============ TRAP (no param): syscall top level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) ; If syscall tracing ongoing, invoke pre-post-hooks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) GET_CURR_THR_INFO_FLAGS r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) btst r10, TIF_SYSCALL_TRACE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bnz tracesys ; this never comes back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ;============ Normal syscall case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ; syscall num shd not exceed the total system calls avail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) cmp r8, NR_syscalls - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) mov.hi r0, -ENOSYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) bhi .Lret_from_system_call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ; Offset into the syscall_table and call handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ld.as r9,[sys_call_table, r8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) jl [r9] ; Entry into Sys Call Handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .Lret_from_system_call:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) st r0, [sp, PT_r0] ; sys call return value in pt_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ; fall through to ret_from_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) END(EV_Trap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ;############# Return from Intr/Excp/Trap (Linux Specifics) ##############
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ; If ret to user mode do we need to handle signals, schedule() et al.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ENTRY(ret_from_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ; Pre-{IRQ,Trap,Exception} K/U mode from pt_regs->status32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ld r8, [sp, PT_status32] ; returning to User/Kernel Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) bbit0 r8, STATUS_U_BIT, resume_kernel_mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ; Before returning to User mode check-for-and-complete any pending work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ; such as rescheduling/signal-delivery etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) resume_user_mode_begin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ; Disable IRQs to ensures that chk for pending work itself is atomic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ; (and we don't end up missing a NEED_RESCHED/SIGPENDING due to an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ; interim IRQ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) IRQ_DISABLE r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ; Fast Path return to user mode if no pending work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) GET_CURR_THR_INFO_FLAGS r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) and.f 0, r9, _TIF_WORK_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) bz .Lrestore_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ; --- (Slow Path #1) task preemption ---
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) bbit0 r9, TIF_NEED_RESCHED, .Lchk_pend_signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) mov blink, resume_user_mode_begin ; tail-call to U mode ret chks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) j @schedule ; BTST+Bnz causes relo error in link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .Lchk_pend_signals:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) IRQ_ENABLE r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ; --- (Slow Path #2) pending signal ---
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) mov r0, sp ; pt_regs for arg to do_signal()/do_notify_resume()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) GET_CURR_THR_INFO_FLAGS r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) bbit0 r9, TIF_SIGPENDING, .Lchk_notify_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) ; in pt_reg since the "C" ABI (kernel code) will automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ; save/restore callee-saved regs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ; However, here we need to explicitly save callee regs because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ; (i) If this signal causes coredump - full regfile needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ; (ii) If signal is SIGTRAP/SIGSTOP, task is being traced thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ; tracer might call PEEKUSR(CALLEE reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ; NOTE: SP will grow up by size of CALLEE Reg-File
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) SAVE_CALLEE_SAVED_USER ; clobbers r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ; save location of saved Callee Regs @ thread_struct->callee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) st sp, [r10, THREAD_CALLEE_REG]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) bl @do_signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ; Ideally we want to discard the Callee reg above, however if this was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ; a tracing signal, tracer could have done a POKEUSR(CALLEE reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) RESTORE_CALLEE_SAVED_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) b resume_user_mode_begin ; loop back to start of U mode ret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ; --- (Slow Path #3) notify_resume ---
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .Lchk_notify_resume:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) btst r9, TIF_NOTIFY_RESUME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) blnz @do_notify_resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) b resume_user_mode_begin ; unconditionally back to U mode ret chks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ; for single exit point from this block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) resume_kernel_mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ; Disable Interrupts from this point on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ; CONFIG_PREEMPTION: This is a must for preempt_schedule_irq()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ; !CONFIG_PREEMPTION: To ensure restore_regs is intr safe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) IRQ_DISABLE r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #ifdef CONFIG_PREEMPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ; Can't preempt if preemption disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) GET_CURR_THR_INFO_FROM_SP r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ld r8, [r10, THREAD_INFO_PREEMPT_COUNT]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) brne r8, 0, .Lrestore_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ; check if this task's NEED_RESCHED flag set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ld r9, [r10, THREAD_INFO_FLAGS]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) bbit0 r9, TIF_NEED_RESCHED, .Lrestore_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ; Invoke PREEMPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) jl preempt_schedule_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ; preempt_schedule_irq() always returns with IRQ disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) b .Lrestore_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ##### DONT ADD CODE HERE - .Lrestore_regs actually follows in entry-<isa>.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)