Blame view
arch/sh/kernel/entry-common.S
7.9 KB
336f1d326 sh: Fix up restor... |
1 |
/* |
de3984064 sh: Exception vec... |
2 |
* Copyright (C) 1999, 2000, 2002 Niibe Yutaka |
336f1d326 sh: Fix up restor... |
3 |
* Copyright (C) 2003 - 2008 Paul Mundt |
de3984064 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 sh: Add CFI annot... |
46 |
#include <asm/dwarf.h> |
de3984064 sh: Exception vec... |
47 48 |
#if defined(CONFIG_PREEMPT) |
fd78a76ae sh: Rework irqfla... |
49 |
# define preempt_stop() cli ; TRACE_IRQS_OFF |
de3984064 sh: Exception vec... |
50 51 52 53 |
#else # define preempt_stop() # define resume_kernel __restore_all #endif |
de3984064 sh: Exception vec... |
54 55 56 57 |
.align 2 ENTRY(exception_error) ! |
fd78a76ae sh: Rework irqfla... |
58 |
TRACE_IRQS_ON |
de3984064 sh: Exception vec... |
59 |
sti |
f413d0d9f sh: Use a jump ca... |
60 |
mov.l 1f, r0 |
de3984064 sh: Exception vec... |
61 62 |
jmp @r0 nop |
de3984064 sh: Exception vec... |
63 |
.align 2 |
f413d0d9f sh: Use a jump ca... |
64 |
1: .long do_exception_error |
de3984064 sh: Exception vec... |
65 66 67 |
.align 2 ret_from_exception: |
cafb0ddac sh: Add CFI annot... |
68 69 70 |
CFI_STARTPROC simple CFI_DEF_CFA r14, 0 CFI_REL_OFFSET 17, 64 |
142698282 sh: Correct the o... |
71 |
CFI_REL_OFFSET 15, 60 |
cafb0ddac sh: Add CFI annot... |
72 |
CFI_REL_OFFSET 14, 56 |
142698282 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 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 sh: resume_kernel... |
93 |
cli |
f3a830886 sh: Add a few mis... |
94 |
TRACE_IRQS_OFF |
de3984064 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 sh: Remove implic... |
105 106 107 |
shlr r0 and #(0xf0>>1), r0 ! interrupts off (exception path)? cmp/eq #(0xf0>>1), r0 |
de3984064 sh: Exception vec... |
108 |
bt noresched |
afbfb52e4 sh: stacktrace/lo... |
109 |
mov.l 3f, r0 |
323b8c410 sh: resume_kernel... |
110 |
jsr @r0 ! call preempt_schedule_irq |
afbfb52e4 sh: stacktrace/lo... |
111 |
nop |
de3984064 sh: Exception vec... |
112 113 |
bra need_resched nop |
afbfb52e4 sh: stacktrace/lo... |
114 |
|
de3984064 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 sh: resume_kernel... |
122 |
3: .long preempt_schedule_irq |
de3984064 sh: Exception vec... |
123 124 125 126 127 |
#endif ENTRY(resume_userspace) ! r8: current_thread_info cli |
457b64618 sh: Fix a TRACE_I... |
128 |
TRACE_IRQS_OFF |
de3984064 sh: Exception vec... |
129 |
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
c652d780c sh: Add ftrace sy... |
130 |
tst #(_TIF_WORK_MASK & 0xff), r0 |
de3984064 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 sh: TS_RESTORE_SI... |
140 |
tst #_TIF_SIGPENDING, r0 |
de3984064 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 sh: Ensure IRQs a... |
146 |
sti |
de3984064 sh: Exception vec... |
147 148 149 150 151 |
mov.l 2f, r1 mov.l 3f, r0 jmp @r1 lds r0, pr work_resched: |
de3984064 sh: Exception vec... |
152 153 154 155 |
mov.l 1f, r1 jsr @r1 ! schedule nop cli |
fd78a76ae sh: Rework irqfla... |
156 |
TRACE_IRQS_OFF |
de3984064 sh: Exception vec... |
157 158 |
! mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
c652d780c sh: Add ftrace sy... |
159 |
tst #(_TIF_WORK_MASK & 0xff), r0 |
de3984064 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 sh: Don't miss pe... |
167 |
3: .long resume_userspace |
de3984064 sh: Exception vec... |
168 169 170 171 172 |
.align 2 syscall_exit_work: ! r0: current_thread_info->flags ! r8: current_thread_info |
c652d780c sh: Add ftrace sy... |
173 |
tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0 |
de3984064 sh: Exception vec... |
174 175 |
bt/s work_pending tst #_TIF_NEED_RESCHED, r0 |
fd78a76ae sh: Rework irqfla... |
176 |
TRACE_IRQS_ON |
de3984064 sh: Exception vec... |
177 |
sti |
1322b9def sh: syscall audit... |
178 |
mov r15, r4 |
ab99c733a sh: Make syscall ... |
179 |
mov.l 8f, r0 ! do_syscall_trace_leave |
de3984064 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 sh: syscall audit... |
188 |
mov r15, r4 |
ab99c733a sh: Make syscall ... |
189 |
mov.l 7f, r11 ! Call do_syscall_trace_enter which notifies |
de3984064 sh: Exception vec... |
190 191 |
jsr @r11 ! superior (will chomp R[0-7]) nop |
ab99c733a sh: Make syscall ... |
192 |
mov.l r0, @(OFF_R0,r15) ! Save return value |
de3984064 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 sh: Fix syscall t... |
205 |
! |
de3984064 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 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 sh: Exception vec... |
228 229 230 231 |
jmp @r0 nop .align 2 |
f3a830886 sh: Add a few mis... |
232 |
3: .long restore_all |
de3984064 sh: Exception vec... |
233 |
|
e0969e0c9 sh: Fix syscall t... |
234 |
.align 2 |
e0969e0c9 sh: Fix syscall t... |
235 |
syscall_badsys: ! Bad syscall number |
561c2bccc sh: Fix up thread... |
236 |
get_current_thread_info r8, r0 |
e0969e0c9 sh: Fix syscall t... |
237 238 239 |
mov #-ENOSYS, r0 bra resume_userspace mov.l r0, @(OFF_R0,r15) ! Return value |
f413d0d9f 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 sh: Fix up restor... |
256 257 258 |
jsr @r8 nop bra __restore_all |
f413d0d9f sh: Use a jump ca... |
259 |
nop |
cafb0ddac sh: Add CFI annot... |
260 |
CFI_ENDPROC |
f413d0d9f sh: Use a jump ca... |
261 262 263 |
.align 2 1: .long debug_trap_table |
e0969e0c9 sh: Fix syscall t... |
264 |
|
de3984064 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 sh: Use a jump ca... |
271 |
* TRA: (number of arguments + ABI revision) x 4 |
de3984064 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 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 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 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 sh: Exception vec... |
305 |
ENTRY(system_call) |
0b930489b sh: Setup the fra... |
306 |
setup_frame_reg |
de3984064 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 sh: Generic kgdb ... |
311 312 313 314 |
mov #OFF_TRA, r10 add r15, r10 mov.l r8, @r10 ! set TRA value to tra |
f413d0d9f sh: Use a jump ca... |
315 316 317 318 |
/* * Check the trap type */ mov #((0x20 << 2) - 1), r9 |
de3984064 sh: Exception vec... |
319 |
cmp/hi r9, r8 |
f413d0d9f sh: Use a jump ca... |
320 |
bt/s debug_trap ! it's a debug trap.. |
ab6e570ba sh: Generic kgdb ... |
321 |
nop |
fd78a76ae sh: Rework irqfla... |
322 |
TRACE_IRQS_ON |
de3984064 sh: Exception vec... |
323 |
sti |
afbfb52e4 sh: stacktrace/lo... |
324 |
|
de3984064 sh: Exception vec... |
325 |
! |
e0969e0c9 sh: Fix syscall t... |
326 |
get_current_thread_info r8, r10 |
de3984064 sh: Exception vec... |
327 |
mov.l @(TI_FLAGS,r8), r8 |
c652d780c sh: Add ftrace sy... |
328 329 |
mov #(_TIF_WORK_SYSCALL_MASK & 0xff), r10 mov #(_TIF_WORK_SYSCALL_MASK >> 8), r9 |
de3984064 sh: Exception vec... |
330 |
tst r10, r8 |
c652d780c sh: Add ftrace sy... |
331 332 333 |
shll8 r9 bf syscall_trace_entry tst r9, r8 |
de3984064 sh: Exception vec... |
334 335 |
bf syscall_trace_entry ! |
e0969e0c9 sh: Fix syscall t... |
336 337 338 339 |
mov.l 2f, r8 ! Number of syscalls cmp/hs r8, r3 bt syscall_badsys ! |
de3984064 sh: Exception vec... |
340 |
syscall_call: |
e0969e0c9 sh: Fix syscall t... |
341 |
shll2 r3 ! x4 |
de3984064 sh: Exception vec... |
342 |
mov.l 3f, r8 ! Load the address of sys_call_table |
e0969e0c9 sh: Fix syscall t... |
343 344 |
add r8, r3 mov.l @r3, r8 |
de3984064 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 sh: Rework irqfla... |
352 |
TRACE_IRQS_OFF |
de3984064 sh: Exception vec... |
353 354 355 |
! get_current_thread_info r8, r0 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
c652d780c 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 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 sh: Make syscall ... |
370 371 |
7: .long do_syscall_trace_enter 8: .long do_syscall_trace_leave |