Blame view

arch/sh/kernel/entry-common.S 7.9 KB
336f1d326   Paul Mundt   sh: Fix up restor...
1
  /* 
de3984064   Yoshinori Sato   sh: Exception vec...
2
   *  Copyright (C) 1999, 2000, 2002  Niibe Yutaka
336f1d326   Paul Mundt   sh: Fix up restor...
3
   *  Copyright (C) 2003 - 2008  Paul Mundt
de3984064   Yoshinori Sato   sh: Exception vec...
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
   *
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
   */
  
  ! NOTE:
  ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
  ! to be jumped is too far, but it causes illegal slot exception.
  
  /*	
   * entry.S contains the system-call and fault low-level handling routines.
   * This also contains the timer-interrupt handler, as well as all interrupts
   * and faults that can result in a task-switch.
   *
   * NOTE: This code handles signal-recognition, which happens every time
   * after a timer-interrupt and after each system call.
   *
   * NOTE: This code uses a convention that instructions in the delay slot
   * of a transfer-control instruction are indented by an extra space, thus:
   *
   *    jmp	@k0	    ! control-transfer instruction
   *     ldc	k1, ssr     ! delay slot
   *
   * Stack layout in 'ret_from_syscall':
   * 	ptrace needs to have all regs on the stack.
   *	if the order here is changed, it needs to be
   *	updated in ptrace.c and ptrace.h
   *
   *	r0
   *      ...
   *	r15 = stack pointer
   *	spc
   *	pr
   *	ssr
   *	gbr
   *	mach
   *	macl
   *	syscall #
   *
   */
cafb0ddac   Matt Fleming   sh: Add CFI annot...
46
  #include <asm/dwarf.h>
de3984064   Yoshinori Sato   sh: Exception vec...
47
48
  
  #if defined(CONFIG_PREEMPT)
fd78a76ae   Stuart Menefy   sh: Rework irqfla...
49
  #  define preempt_stop()	cli ; TRACE_IRQS_OFF
de3984064   Yoshinori Sato   sh: Exception vec...
50
51
52
53
  #else
  #  define preempt_stop()
  #  define resume_kernel		__restore_all
  #endif
de3984064   Yoshinori Sato   sh: Exception vec...
54
55
56
57
  
  	.align	2
  ENTRY(exception_error)
  	!
fd78a76ae   Stuart Menefy   sh: Rework irqfla...
58
  	TRACE_IRQS_ON
de3984064   Yoshinori Sato   sh: Exception vec...
59
  	sti
f413d0d9f   Paul Mundt   sh: Use a jump ca...
60
  	mov.l	1f, r0
de3984064   Yoshinori Sato   sh: Exception vec...
61
62
  	jmp	@r0
  	 nop
de3984064   Yoshinori Sato   sh: Exception vec...
63
  	.align	2
f413d0d9f   Paul Mundt   sh: Use a jump ca...
64
  1:	.long	do_exception_error
de3984064   Yoshinori Sato   sh: Exception vec...
65
66
67
  
  	.align	2
  ret_from_exception:
cafb0ddac   Matt Fleming   sh: Add CFI annot...
68
69
70
  	CFI_STARTPROC simple
  	CFI_DEF_CFA r14, 0
  	CFI_REL_OFFSET 17, 64
142698282   Matt Fleming   sh: Correct the o...
71
  	CFI_REL_OFFSET 15, 60
cafb0ddac   Matt Fleming   sh: Add CFI annot...
72
  	CFI_REL_OFFSET 14, 56
142698282   Matt Fleming   sh: Correct the o...
73
74
75
76
77
78
  	CFI_REL_OFFSET 13, 52
  	CFI_REL_OFFSET 12, 48
  	CFI_REL_OFFSET 11, 44
  	CFI_REL_OFFSET 10, 40
  	CFI_REL_OFFSET 9, 36
  	CFI_REL_OFFSET 8, 32
de3984064   Yoshinori Sato   sh: Exception vec...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  	preempt_stop()
  ENTRY(ret_from_irq)
  	!
  	mov	#OFF_SR, r0
  	mov.l	@(r0,r15), r0	! get status register
  	shll	r0
  	shll	r0		! kernel space?
  	get_current_thread_info r8, r0
  	bt	resume_kernel	! Yes, it's from kernel, go back soon
  
  #ifdef CONFIG_PREEMPT
  	bra	resume_userspace
  	 nop
  ENTRY(resume_kernel)
323b8c410   Carmelo Amoroso   sh: resume_kernel...
93
  	cli
f3a830886   Matt Fleming   sh: Add a few mis...
94
  	TRACE_IRQS_OFF
de3984064   Yoshinori Sato   sh: Exception vec...
95
96
97
98
99
100
101
102
103
104
  	mov.l	@(TI_PRE_COUNT,r8), r0	! current_thread_info->preempt_count
  	tst	r0, r0
  	bf	noresched
  need_resched:
  	mov.l	@(TI_FLAGS,r8), r0	! current_thread_info->flags
  	tst	#_TIF_NEED_RESCHED, r0	! need_resched set?
  	bt	noresched
  
  	mov	#OFF_SR, r0
  	mov.l	@(r0,r15), r0		! get status register
fea966f75   Stuart Menefy   sh: Remove implic...
105
106
107
  	shlr	r0
  	and	#(0xf0>>1), r0		! interrupts off (exception path)?
  	cmp/eq	#(0xf0>>1), r0
de3984064   Yoshinori Sato   sh: Exception vec...
108
  	bt	noresched
afbfb52e4   Paul Mundt   sh: stacktrace/lo...
109
  	mov.l	3f, r0
323b8c410   Carmelo Amoroso   sh: resume_kernel...
110
  	jsr	@r0			! call preempt_schedule_irq
afbfb52e4   Paul Mundt   sh: stacktrace/lo...
111
  	 nop
de3984064   Yoshinori Sato   sh: Exception vec...
112
113
  	bra	need_resched
  	 nop
afbfb52e4   Paul Mundt   sh: stacktrace/lo...
114

de3984064   Yoshinori Sato   sh: Exception vec...
115
116
117
118
119
120
121
  noresched:
  	bra	__restore_all
  	 nop
  
  	.align 2
  1:	.long	PREEMPT_ACTIVE
  2:	.long	schedule
323b8c410   Carmelo Amoroso   sh: resume_kernel...
122
  3:	.long	preempt_schedule_irq
de3984064   Yoshinori Sato   sh: Exception vec...
123
124
125
126
127
  #endif
  
  ENTRY(resume_userspace)
  	! r8: current_thread_info
  	cli
457b64618   Paul Mundt   sh: Fix a TRACE_I...
128
  	TRACE_IRQS_OFF
de3984064   Yoshinori Sato   sh: Exception vec...
129
  	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
c652d780c   Matt Fleming   sh: Add ftrace sy...
130
  	tst	#(_TIF_WORK_MASK & 0xff), r0
de3984064   Yoshinori Sato   sh: Exception vec...
131
132
133
134
135
136
137
138
139
  	bt/s	__restore_all
  	 tst	#_TIF_NEED_RESCHED, r0
  
  	.align	2
  work_pending:
  	! r0: current_thread_info->flags
  	! r8: current_thread_info
  	! t:  result of "tst	#_TIF_NEED_RESCHED, r0"
  	bf/s	work_resched
56bfc42f6   Paul Mundt   sh: TS_RESTORE_SI...
140
  	 tst	#_TIF_SIGPENDING, r0
de3984064   Yoshinori Sato   sh: Exception vec...
141
142
143
144
145
  work_notifysig:
  	bt/s	__restore_all
  	 mov	r15, r4
  	mov	r12, r5		! set arg1(save_r0)
  	mov	r0, r6
6330c04bb   Paul Mundt   sh: Ensure IRQs a...
146
  	sti
de3984064   Yoshinori Sato   sh: Exception vec...
147
148
149
150
151
  	mov.l	2f, r1
  	mov.l	3f, r0
  	jmp	@r1
  	 lds	r0, pr
  work_resched:
de3984064   Yoshinori Sato   sh: Exception vec...
152
153
154
155
  	mov.l	1f, r1
  	jsr	@r1				! schedule
  	 nop
  	cli
fd78a76ae   Stuart Menefy   sh: Rework irqfla...
156
  	TRACE_IRQS_OFF
de3984064   Yoshinori Sato   sh: Exception vec...
157
158
  	!
  	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
c652d780c   Matt Fleming   sh: Add ftrace sy...
159
  	tst	#(_TIF_WORK_MASK & 0xff), r0
de3984064   Yoshinori Sato   sh: Exception vec...
160
161
162
163
164
165
166
  	bt	__restore_all
  	bra	work_pending
  	 tst	#_TIF_NEED_RESCHED, r0
  
  	.align	2
  1:	.long	schedule
  2:	.long	do_notify_resume
0b1689cfb   Stuart MENEFY   sh: Don't miss pe...
167
  3:	.long	resume_userspace
de3984064   Yoshinori Sato   sh: Exception vec...
168
169
170
171
172
  
  	.align	2
  syscall_exit_work:
  	! r0: current_thread_info->flags
  	! r8: current_thread_info
c652d780c   Matt Fleming   sh: Add ftrace sy...
173
  	tst	#(_TIF_WORK_SYSCALL_MASK & 0xff), r0
de3984064   Yoshinori Sato   sh: Exception vec...
174
175
  	bt/s	work_pending
  	 tst	#_TIF_NEED_RESCHED, r0
fd78a76ae   Stuart Menefy   sh: Rework irqfla...
176
  	TRACE_IRQS_ON
de3984064   Yoshinori Sato   sh: Exception vec...
177
  	sti
1322b9def   Yuichi Nakamura   sh: syscall audit...
178
  	mov	r15, r4
ab99c733a   Paul Mundt   sh: Make syscall ...
179
  	mov.l	8f, r0			! do_syscall_trace_leave
de3984064   Yoshinori Sato   sh: Exception vec...
180
181
182
183
184
185
186
187
  	jsr	@r0
  	 nop
  	bra	resume_userspace
  	 nop
  
  	.align	2
  syscall_trace_entry:
  	!                     	Yes it is traced.
1322b9def   Yuichi Nakamura   sh: syscall audit...
188
  	mov     r15, r4
ab99c733a   Paul Mundt   sh: Make syscall ...
189
  	mov.l	7f, r11		! Call do_syscall_trace_enter which notifies
de3984064   Yoshinori Sato   sh: Exception vec...
190
191
  	jsr	@r11	    	! superior (will chomp R[0-7])
  	 nop
ab99c733a   Paul Mundt   sh: Make syscall ...
192
  	mov.l	r0, @(OFF_R0,r15)	! Save return value
de3984064   Yoshinori Sato   sh: Exception vec...
193
194
195
196
197
198
199
200
201
202
203
204
  	!			Reload R0-R4 from kernel stack, where the
  	!   	    	    	parent may have modified them using
  	!   	    	    	ptrace(POKEUSR).  (Note that R0-R2 are
  	!   	    	    	used by the system call handler directly
  	!   	    	    	from the kernel stack anyway, so don't need
  	!   	    	    	to be reloaded here.)  This allows the parent
  	!   	    	    	to rewrite system calls and args on the fly.
  	mov.l	@(OFF_R4,r15), r4   ! arg0
  	mov.l	@(OFF_R5,r15), r5
  	mov.l	@(OFF_R6,r15), r6
  	mov.l	@(OFF_R7,r15), r7   ! arg3
  	mov.l	@(OFF_R3,r15), r3   ! syscall_nr
e0969e0c9   Stuart Menefy   sh: Fix syscall t...
205
  	!
de3984064   Yoshinori Sato   sh: Exception vec...
206
207
208
209
210
211
212
213
  	mov.l	2f, r10			! Number of syscalls
  	cmp/hs	r10, r3
  	bf	syscall_call
  	mov	#-ENOSYS, r0
  	bra	syscall_exit
  	 mov.l	r0, @(OFF_R0,r15)	! Return value
  
  __restore_all:
f3a830886   Matt Fleming   sh: Add a few mis...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  	mov	#OFF_SR, r0
  	mov.l	@(r0,r15), r0	! get status register
  
  	shlr2	r0
  	and	#0x3c, r0
  	cmp/eq	#0x3c, r0
  	bt	1f
  	TRACE_IRQS_ON
  	bra	2f
  	 nop
  1:
  	TRACE_IRQS_OFF
  2:
  	mov.l	3f, r0
de3984064   Yoshinori Sato   sh: Exception vec...
228
229
230
231
  	jmp	@r0
  	 nop
  
  	.align	2
f3a830886   Matt Fleming   sh: Add a few mis...
232
  3:	.long	restore_all
de3984064   Yoshinori Sato   sh: Exception vec...
233

e0969e0c9   Stuart Menefy   sh: Fix syscall t...
234
  	.align	2
e0969e0c9   Stuart Menefy   sh: Fix syscall t...
235
  syscall_badsys:			! Bad syscall number
561c2bccc   Hideo Saito   sh: Fix up thread...
236
  	get_current_thread_info r8, r0
e0969e0c9   Stuart Menefy   sh: Fix syscall t...
237
238
239
  	mov	#-ENOSYS, r0
  	bra	resume_userspace
  	 mov.l	r0, @(OFF_R0,r15)	! Return value
f413d0d9f   Paul Mundt   sh: Use a jump ca...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
  
  /*
   * The main debug trap handler.
   *
   * r8=TRA (not the trap number!)
   *
   * Note: This assumes that the trapa value is left in its original
   * form (without the shlr2 shift) so the calculation for the jump
   * call table offset remains a simple in place mask.
   */
  debug_trap:
  	mov	r8, r0
  	and	#(0xf << 2), r0
  	mov.l	1f, r8
  	add	r0, r8
  	mov.l	@r8, r8
336f1d326   Paul Mundt   sh: Fix up restor...
256
257
258
  	jsr	@r8
  	 nop
  	bra	__restore_all
f413d0d9f   Paul Mundt   sh: Use a jump ca...
259
  	 nop
cafb0ddac   Matt Fleming   sh: Add CFI annot...
260
  	CFI_ENDPROC
f413d0d9f   Paul Mundt   sh: Use a jump ca...
261
262
263
  
  	.align	2
  1:	.long	debug_trap_table
e0969e0c9   Stuart Menefy   sh: Fix syscall t...
264

de3984064   Yoshinori Sato   sh: Exception vec...
265
266
267
268
269
270
  /*
   * Syscall interface:
   *
   *	Syscall #: R3
   *	Arguments #0 to #3: R4--R7
   *	Arguments #4 to #6: R0, R1, R2
f413d0d9f   Paul Mundt   sh: Use a jump ca...
271
   *	TRA: (number of arguments + ABI revision) x 4
de3984064   Yoshinori Sato   sh: Exception vec...
272
273
274
275
276
   *
   * This code also handles delegating other traps to the BIOS/gdb stub
   * according to:
   *
   * Trap number
f413d0d9f   Paul Mundt   sh: Use a jump ca...
277
278
279
280
281
282
283
   * (TRA>>2)	Purpose
   * --------	-------
   * 0x00-0x0f	original SH-3/4 syscall ABI (not in general use).
   * 0x10-0x1f	general SH-3/4 syscall ABI.
   * 0x20-0x2f	syscall ABI for SH-2 parts.
   * 0x30-0x3f	debug traps used by the kernel.
   * 0x40-0xff	Not supported by all parts, so left unhandled.
de3984064   Yoshinori Sato   sh: Exception vec...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
   *
   * Note: When we're first called, the TRA value must be shifted
   * right 2 bits in order to get the value that was used as the "trapa"
   * argument.
   */
  
  	.align	2
  	.globl	ret_from_fork
  ret_from_fork:
  	mov.l	1f, r8
  	jsr	@r8
  	 mov	r0, r4
  	bra	syscall_exit
  	 nop
  	.align	2
  1:	.long	schedule_tail
f413d0d9f   Paul Mundt   sh: Use a jump ca...
300
301
302
303
304
  
  /*
   * The poorly named main trapa decode and dispatch routine, for
   * system calls and debug traps through their respective jump tables.
   */
de3984064   Yoshinori Sato   sh: Exception vec...
305
  ENTRY(system_call)
0b930489b   Matt Fleming   sh: Setup the fra...
306
  	setup_frame_reg
de3984064   Yoshinori Sato   sh: Exception vec...
307
308
309
310
  #if !defined(CONFIG_CPU_SH2)
  	mov.l	1f, r9
  	mov.l	@r9, r8		! Read from TRA (Trap Address) Register
  #endif
ab6e570ba   Paul Mundt   sh: Generic kgdb ...
311
312
313
314
  
  	mov	#OFF_TRA, r10
  	add	r15, r10
  	mov.l	r8, @r10		! set TRA value to tra
f413d0d9f   Paul Mundt   sh: Use a jump ca...
315
316
317
318
  	/*
  	 * Check the trap type
  	 */
  	mov	#((0x20 << 2) - 1), r9
de3984064   Yoshinori Sato   sh: Exception vec...
319
  	cmp/hi	r9, r8
f413d0d9f   Paul Mundt   sh: Use a jump ca...
320
  	bt/s	debug_trap		! it's a debug trap..
ab6e570ba   Paul Mundt   sh: Generic kgdb ...
321
  	 nop
fd78a76ae   Stuart Menefy   sh: Rework irqfla...
322
  	TRACE_IRQS_ON
de3984064   Yoshinori Sato   sh: Exception vec...
323
  	sti
afbfb52e4   Paul Mundt   sh: stacktrace/lo...
324

de3984064   Yoshinori Sato   sh: Exception vec...
325
  	!
e0969e0c9   Stuart Menefy   sh: Fix syscall t...
326
  	get_current_thread_info r8, r10
de3984064   Yoshinori Sato   sh: Exception vec...
327
  	mov.l	@(TI_FLAGS,r8), r8
c652d780c   Matt Fleming   sh: Add ftrace sy...
328
329
  	mov	#(_TIF_WORK_SYSCALL_MASK & 0xff), r10
  	mov	#(_TIF_WORK_SYSCALL_MASK >> 8), r9
de3984064   Yoshinori Sato   sh: Exception vec...
330
  	tst	r10, r8
c652d780c   Matt Fleming   sh: Add ftrace sy...
331
332
333
  	shll8	r9
  	bf	syscall_trace_entry
  	tst	r9, r8
de3984064   Yoshinori Sato   sh: Exception vec...
334
335
  	bf	syscall_trace_entry
  	!
e0969e0c9   Stuart Menefy   sh: Fix syscall t...
336
337
338
339
  	mov.l	2f, r8			! Number of syscalls
  	cmp/hs	r8, r3
  	bt	syscall_badsys
  	!
de3984064   Yoshinori Sato   sh: Exception vec...
340
  syscall_call:
e0969e0c9   Stuart Menefy   sh: Fix syscall t...
341
  	shll2	r3		! x4
de3984064   Yoshinori Sato   sh: Exception vec...
342
  	mov.l	3f, r8		! Load the address of sys_call_table
e0969e0c9   Stuart Menefy   sh: Fix syscall t...
343
344
  	add	r8, r3
  	mov.l	@r3, r8
de3984064   Yoshinori Sato   sh: Exception vec...
345
346
347
348
349
350
351
  	jsr	@r8	    	! jump to specific syscall handler
  	 nop
  	mov.l	@(OFF_R0,r15), r12		! save r0
  	mov.l	r0, @(OFF_R0,r15)		! save the return value
  	!
  syscall_exit:
  	cli
fd78a76ae   Stuart Menefy   sh: Rework irqfla...
352
  	TRACE_IRQS_OFF
de3984064   Yoshinori Sato   sh: Exception vec...
353
354
355
  	!
  	get_current_thread_info r8, r0
  	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
c652d780c   Matt Fleming   sh: Add ftrace sy...
356
357
358
359
360
  	tst	#(_TIF_ALLWORK_MASK & 0xff), r0
  	mov	#(_TIF_ALLWORK_MASK >> 8), r1
  	bf	syscall_exit_work
  	shlr8	r0
  	tst	r0, r1
de3984064   Yoshinori Sato   sh: Exception vec...
361
362
363
364
365
366
367
368
369
  	bf	syscall_exit_work
  	bra	__restore_all
  	 nop
  	.align	2
  #if !defined(CONFIG_CPU_SH2)
  1:	.long	TRA
  #endif
  2:	.long	NR_syscalls
  3:	.long	sys_call_table
ab99c733a   Paul Mundt   sh: Make syscall ...
370
371
  7:	.long	do_syscall_trace_enter
  8:	.long	do_syscall_trace_leave