~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sh/kernel/entry-common.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0
  2  *
  3  *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
  4  *  Copyright (C) 2003 - 2008  Paul Mundt
  5  */
  6 
  7 ! NOTE:
  8 ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
  9 ! to be jumped is too far, but it causes illegal slot exception.
 10 
 11 /*      
 12  * entry.S contains the system-call and fault low-level handling routines.
 13  * This also contains the timer-interrupt handler, as well as all interrupts
 14  * and faults that can result in a task-switch.
 15  *
 16  * NOTE: This code handles signal-recognition, which happens every time
 17  * after a timer-interrupt and after each system call.
 18  *
 19  * NOTE: This code uses a convention that instructions in the delay slot
 20  * of a transfer-control instruction are indented by an extra space, thus:
 21  *
 22  *    jmp       @k0         ! control-transfer instruction
 23  *     ldc      k1, ssr     ! delay slot
 24  *
 25  * Stack layout in 'ret_from_syscall':
 26  *      ptrace needs to have all regs on the stack.
 27  *      if the order here is changed, it needs to be
 28  *      updated in ptrace.c and ptrace.h
 29  *
 30  *      r0
 31  *      ...
 32  *      r15 = stack pointer
 33  *      spc
 34  *      pr
 35  *      ssr
 36  *      gbr
 37  *      mach
 38  *      macl
 39  *      syscall #
 40  *
 41  */
 42 #include <asm/dwarf.h>
 43 
 44 #if defined(CONFIG_PREEMPTION)
 45 #  define preempt_stop()        cli ; TRACE_IRQS_OFF
 46 #else
 47 #  define preempt_stop()
 48 #  define resume_kernel         __restore_all
 49 #endif
 50 
 51 
 52         .align  2
 53 ENTRY(exception_error)
 54         !
 55         TRACE_IRQS_ON
 56         sti
 57         mov.l   1f, r0
 58         jmp     @r0
 59          nop
 60 
 61         .align  2
 62 1:      .long   do_exception_error
 63 
 64         .align  2
 65 ret_from_exception:
 66         CFI_STARTPROC simple
 67         CFI_DEF_CFA r14, 0
 68         CFI_REL_OFFSET 17, 64
 69         CFI_REL_OFFSET 15, 60
 70         CFI_REL_OFFSET 14, 56
 71         CFI_REL_OFFSET 13, 52
 72         CFI_REL_OFFSET 12, 48
 73         CFI_REL_OFFSET 11, 44
 74         CFI_REL_OFFSET 10, 40
 75         CFI_REL_OFFSET 9, 36
 76         CFI_REL_OFFSET 8, 32
 77         preempt_stop()
 78 ENTRY(ret_from_irq)
 79         !
 80         mov     #OFF_SR, r0
 81         mov.l   @(r0,r15), r0   ! get status register
 82         shll    r0
 83         shll    r0              ! kernel space?
 84         get_current_thread_info r8, r0
 85         bt      resume_kernel   ! Yes, it's from kernel, go back soon
 86 
 87 #ifdef CONFIG_PREEMPTION
 88         bra     resume_userspace
 89          nop
 90 ENTRY(resume_kernel)
 91         cli
 92         TRACE_IRQS_OFF
 93         mov.l   @(TI_PRE_COUNT,r8), r0  ! current_thread_info->preempt_count
 94         tst     r0, r0
 95         bf      noresched
 96 need_resched:
 97         mov.l   @(TI_FLAGS,r8), r0      ! current_thread_info->flags
 98         tst     #_TIF_NEED_RESCHED, r0  ! need_resched set?
 99         bt      noresched
100 
101         mov     #OFF_SR, r0
102         mov.l   @(r0,r15), r0           ! get status register
103         shlr    r0
104         and     #(0xf0>>1), r0          ! interrupts off (exception path)?
105         cmp/eq  #(0xf0>>1), r0
106         bt      noresched
107         mov.l   1f, r0
108         jsr     @r0                     ! call preempt_schedule_irq
109          nop
110         bra     need_resched
111          nop
112 
113 noresched:
114         bra     __restore_all
115          nop
116 
117         .align 2
118 1:      .long   preempt_schedule_irq
119 #endif
120 
121 ENTRY(resume_userspace)
122         ! r8: current_thread_info
123         cli
124         TRACE_IRQS_OFF
125         mov.l   @(TI_FLAGS,r8), r0              ! current_thread_info->flags
126         tst     #(_TIF_WORK_MASK & 0xff), r0
127         bt/s    __restore_all
128          tst    #_TIF_NEED_RESCHED, r0
129 
130         .align  2
131 work_pending:
132         ! r0: current_thread_info->flags
133         ! r8: current_thread_info
134         ! t:  result of "tst    #_TIF_NEED_RESCHED, r0"
135         bf/s    work_resched
136          tst    #(_TIF_SIGPENDING | _TIF_NOTIFY_RESUME), r0
137 work_notifysig:
138         bt/s    __restore_all
139          mov    r15, r4
140         mov     r12, r5         ! set arg1(save_r0)
141         mov     r0, r6
142         sti
143         mov.l   2f, r1
144         mov.l   3f, r0
145         jmp     @r1
146          lds    r0, pr
147 work_resched:
148         mov.l   1f, r1
149         jsr     @r1                             ! schedule
150          nop
151         cli
152         TRACE_IRQS_OFF
153         !
154         mov.l   @(TI_FLAGS,r8), r0              ! current_thread_info->flags
155         tst     #(_TIF_WORK_MASK & 0xff), r0
156         bt      __restore_all
157         bra     work_pending
158          tst    #_TIF_NEED_RESCHED, r0
159 
160         .align  2
161 1:      .long   schedule
162 2:      .long   do_notify_resume
163 3:      .long   resume_userspace
164 
165         .align  2
166 syscall_exit_work:
167         ! r0: current_thread_info->flags
168         ! r8: current_thread_info
169         tst     #(_TIF_WORK_SYSCALL_MASK & 0xff), r0
170         bt/s    work_pending
171          tst    #_TIF_NEED_RESCHED, r0
172         TRACE_IRQS_ON
173         sti
174         mov     r15, r4
175         mov.l   8f, r0                  ! do_syscall_trace_leave
176         jsr     @r0
177          nop
178         bra     resume_userspace
179          nop
180 
181 __restore_all:
182         mov     #OFF_SR, r0
183         mov.l   @(r0,r15), r0   ! get status register
184 
185         shlr2   r0
186         and     #0x3c, r0
187         cmp/eq  #0x3c, r0
188         bt      1f
189         TRACE_IRQS_ON
190         bra     2f
191          nop
192 1:
193         TRACE_IRQS_OFF
194 2:
195         mov.l   3f, r0
196         jmp     @r0
197          nop
198 
199         .align  2
200 3:      .long   restore_all
201 
202         .align  2
203 syscall_badsys:                 ! Bad syscall number
204         get_current_thread_info r8, r0
205         mov     #-ENOSYS, r0
206         bra     resume_userspace
207          mov.l  r0, @(OFF_R0,r15)       ! Return value
208 
209 /*
210  * The main debug trap handler.
211  *
212  * r8=TRA (not the trap number!)
213  *
214  * Note: This assumes that the trapa value is left in its original
215  * form (without the shlr2 shift) so the calculation for the jump
216  * call table offset remains a simple in place mask.
217  */
218 debug_trap:
219         mov     r8, r0
220         and     #(0xf << 2), r0
221         mov.l   1f, r8
222         add     r0, r8
223         mov.l   @r8, r8
224         jsr     @r8
225          nop
226         bra     ret_from_exception
227          nop
228         CFI_ENDPROC
229 
230         .align  2
231 1:      .long   debug_trap_table
232 
233 /*
234  * Syscall interface:
235  *
236  *      Syscall #: R3
237  *      Arguments #0 to #3: R4--R7
238  *      Arguments #4 to #6: R0, R1, R2
239  *      TRA: See following table.
240  *
241  * (TRA>>2)     Purpose
242  * --------     -------
243  * 0x00-0x0f    original SH-3/4 syscall ABI (not in general use).
244  * 0x10-0x1f    general SH-3/4 syscall ABI.
245  *      0x1f    unified SH-2/3/4 syscall ABI (preferred).
246  * 0x20-0x2f    original SH-2 syscall ABI.
247  * 0x30-0x3f    debug traps used by the kernel.
248  * 0x40-0xff    Not supported by all parts, so left unhandled.
249  *
250  * For making system calls, any trap number in the range for the
251  * given cpu model may be used, but the unified trap number 0x1f is
252  * preferred for compatibility with all models.
253  *
254  * The low bits of the trap number were once documented as matching
255  * the number of arguments, but they were never actually used as such
256  * by the kernel. SH-2 originally used its own separate trap range
257  * because several hardware exceptions fell in the range used for the
258  * SH-3/4 syscall ABI.
259  *
260  * This code also handles delegating other traps to the BIOS/gdb stub.
261  *
262  * Note: When we're first called, the TRA value must be shifted
263  * right 2 bits in order to get the value that was used as the "trapa"
264  * argument.
265  */
266 
267         .align  2
268         .globl  ret_from_fork
269 ret_from_fork:
270         mov.l   1f, r8
271         jsr     @r8
272          mov    r0, r4
273         bra     syscall_exit
274          nop
275 
276         .align  2
277         .globl  ret_from_kernel_thread
278 ret_from_kernel_thread:
279         mov.l   1f, r8
280         jsr     @r8
281          mov    r0, r4
282         mov.l   @(OFF_R5,r15), r5   ! fn
283         jsr     @r5
284          mov.l  @(OFF_R4,r15), r4   ! arg
285         bra     syscall_exit
286          nop
287 
288         .align  2
289 1:      .long   schedule_tail
290 
291 /*
292  * The poorly named main trapa decode and dispatch routine, for
293  * system calls and debug traps through their respective jump tables.
294  */
295 ENTRY(system_call)
296         setup_frame_reg
297 #if !defined(CONFIG_CPU_SH2)
298         mov.l   1f, r9
299         mov.l   @r9, r8         ! Read from TRA (Trap Address) Register
300 #endif
301 
302         mov     #OFF_TRA, r10
303         add     r15, r10
304         mov.l   r8, @r10                ! set TRA value to tra
305 
306         /*
307          * Check the trap type
308          */
309         mov     #((0x20 << 2) - 1), r9
310         cmp/hi  r9, r8
311         bt/s    debug_trap              ! it's a debug trap..
312          nop
313 
314         TRACE_IRQS_ON
315         sti
316 
317         !
318         get_current_thread_info r8, r10
319         mov.l   @(TI_FLAGS,r8), r8
320         mov     #(_TIF_WORK_SYSCALL_MASK & 0xff), r10
321         mov     #(_TIF_WORK_SYSCALL_MASK >> 8), r9
322         tst     r10, r8
323         shll8   r9
324         bf      syscall_trace_entry
325         tst     r9, r8
326         bf      syscall_trace_entry
327         !
328         mov.l   6f, r8                  ! Number of syscalls
329         cmp/hs  r8, r3
330         bt      syscall_badsys
331         !
332 syscall_call:
333         shll2   r3              ! x4
334         mov.l   3f, r8          ! Load the address of sys_call_table
335         add     r8, r3
336         mov.l   @r3, r8
337         mov.l   @(OFF_R2,r15), r2
338         mov.l   @(OFF_R1,r15), r1
339         mov.l   @(OFF_R0,r15), r0
340         mov.l   r2, @-r15
341         mov.l   r1, @-r15
342         mov.l   r0, @-r15
343         jsr     @r8             ! jump to specific syscall handler
344          nop
345         add     #12, r15
346         mov.l   @(OFF_R0,r15), r12              ! save r0
347         mov.l   r0, @(OFF_R0,r15)               ! save the return value
348         !
349 syscall_exit:
350         cli
351         TRACE_IRQS_OFF
352         !
353         get_current_thread_info r8, r0
354         mov.l   @(TI_FLAGS,r8), r0              ! current_thread_info->flags
355         tst     #(_TIF_ALLWORK_MASK & 0xff), r0
356         mov     #(_TIF_ALLWORK_MASK >> 8), r1
357         bf      syscall_exit_work
358         shlr8   r0
359         tst     r0, r1
360         bf      syscall_exit_work
361         bra     __restore_all
362          nop
363 
364         .align  2
365 syscall_trace_entry:
366         !                       Yes it is traced.
367         mov     r15, r4
368         mov.l   7f, r11         ! Call do_syscall_trace_enter which notifies
369         jsr     @r11            ! superior (will chomp R[0-7])
370          nop
371         cmp/eq  #-1, r0
372         bt      syscall_exit
373         !                       Reload R0-R4 from kernel stack, where the
374         !                       parent may have modified them using
375         !                       ptrace(POKEUSR).  (Note that R0-R2 are
376         !                       reloaded from the kernel stack by syscall_call
377         !                       below, so don't need to be reloaded here.)
378         !                       This allows the parent to rewrite system calls
379         !                       and args on the fly.
380         mov.l   @(OFF_R4,r15), r4   ! arg0
381         mov.l   @(OFF_R5,r15), r5
382         mov.l   @(OFF_R6,r15), r6
383         mov.l   @(OFF_R7,r15), r7   ! arg3
384         mov.l   @(OFF_R3,r15), r3   ! syscall_nr
385         !
386         mov.l   6f, r10                 ! Number of syscalls
387         cmp/hs  r10, r3
388         bf      syscall_call
389         mov     #-ENOSYS, r0
390         bra     syscall_exit
391          mov.l  r0, @(OFF_R0,r15)       ! Return value
392 
393         .align  2
394 #if !defined(CONFIG_CPU_SH2)
395 1:      .long   TRA
396 #endif
397 6:      .long   NR_syscalls
398 3:      .long   sys_call_table
399 7:      .long   do_syscall_trace_enter
400 8:      .long   do_syscall_trace_leave

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php