aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/entry_32.S
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-01-09 13:03:44 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-09 13:03:44 -0500
commit6150c32589d1976ca8a5c987df951088c05a7542 (patch)
tree94073696576323ff966e365d8c47b8ecd8372f97 /arch/powerpc/kernel/entry_32.S
parent44637a12f80b80157d9c1bc5b7d6ef09c9e05713 (diff)
parentbe42d5fa3772241b8ecebd443f1fb36247959c54 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
Diffstat (limited to 'arch/powerpc/kernel/entry_32.S')
-rw-r--r--arch/powerpc/kernel/entry_32.S167
1 files changed, 96 insertions, 71 deletions
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 2e99ae41723c..036b71d2adfc 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -200,8 +200,6 @@ _GLOBAL(DoSyscall)
200 bl do_show_syscall 200 bl do_show_syscall
201#endif /* SHOW_SYSCALLS */ 201#endif /* SHOW_SYSCALLS */
202 rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 202 rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
203 li r11,0
204 stb r11,TI_SC_NOERR(r10)
205 lwz r11,TI_FLAGS(r10) 203 lwz r11,TI_FLAGS(r10)
206 andi. r11,r11,_TIF_SYSCALL_T_OR_A 204 andi. r11,r11,_TIF_SYSCALL_T_OR_A
207 bne- syscall_dotrace 205 bne- syscall_dotrace
@@ -222,25 +220,21 @@ ret_from_syscall:
222 bl do_show_syscall_exit 220 bl do_show_syscall_exit
223#endif 221#endif
224 mr r6,r3 222 mr r6,r3
225 li r11,-_LAST_ERRNO
226 cmplw 0,r3,r11
227 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 223 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
228 blt+ 30f
229 lbz r11,TI_SC_NOERR(r12)
230 cmpwi r11,0
231 bne 30f
232 neg r3,r3
233 lwz r10,_CCR(r1) /* Set SO bit in CR */
234 oris r10,r10,0x1000
235 stw r10,_CCR(r1)
236
237 /* disable interrupts so current_thread_info()->flags can't change */ 224 /* disable interrupts so current_thread_info()->flags can't change */
23830: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 225 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
239 SYNC 226 SYNC
240 MTMSRD(r10) 227 MTMSRD(r10)
241 lwz r9,TI_FLAGS(r12) 228 lwz r9,TI_FLAGS(r12)
242 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) 229 li r8,-_LAST_ERRNO
230 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
243 bne- syscall_exit_work 231 bne- syscall_exit_work
232 cmplw 0,r3,r8
233 blt+ syscall_exit_cont
234 lwz r11,_CCR(r1) /* Load CR */
235 neg r3,r3
236 oris r11,r11,0x1000 /* Set SO bit in CR */
237 stw r11,_CCR(r1)
244syscall_exit_cont: 238syscall_exit_cont:
245#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 239#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
246 /* If the process has its own DBCR0 value, load it up. The single 240 /* If the process has its own DBCR0 value, load it up. The single
@@ -292,46 +286,113 @@ syscall_dotrace:
292 b syscall_dotrace_cont 286 b syscall_dotrace_cont
293 287
294syscall_exit_work: 288syscall_exit_work:
295 stw r6,RESULT(r1) /* Save result */ 289 andi. r0,r9,_TIF_RESTOREALL
290 bne- 2f
291 cmplw 0,r3,r8
292 blt+ 1f
293 andi. r0,r9,_TIF_NOERROR
294 bne- 1f
295 lwz r11,_CCR(r1) /* Load CR */
296 neg r3,r3
297 oris r11,r11,0x1000 /* Set SO bit in CR */
298 stw r11,_CCR(r1)
299
3001: stw r6,RESULT(r1) /* Save result */
296 stw r3,GPR3(r1) /* Update return value */ 301 stw r3,GPR3(r1) /* Update return value */
297 andi. r0,r9,_TIF_SYSCALL_T_OR_A 3022: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
298 beq 5f 303 beq 4f
299 ori r10,r10,MSR_EE 304
300 SYNC 305 /* Clear per-syscall TIF flags if any are set, but _leave_
301 MTMSRD(r10) /* re-enable interrupts */ 306 _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
307 yet. */
308
309 li r11,_TIF_PERSYSCALL_MASK
310 addi r12,r12,TI_FLAGS
3113: lwarx r8,0,r12
312 andc r8,r8,r11
313#ifdef CONFIG_IBM405_ERR77
314 dcbt 0,r12
315#endif
316 stwcx. r8,0,r12
317 bne- 3b
318 subi r12,r12,TI_FLAGS
319
3204: /* Anything which requires enabling interrupts? */
321 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
322 beq 7f
323
324 /* Save NVGPRS if they're not saved already */
302 lwz r4,_TRAP(r1) 325 lwz r4,_TRAP(r1)
303 andi. r4,r4,1 326 andi. r4,r4,1
304 beq 4f 327 beq 5f
305 SAVE_NVGPRS(r1) 328 SAVE_NVGPRS(r1)
306 li r4,0xc00 329 li r4,0xc00
307 stw r4,_TRAP(r1) 330 stw r4,_TRAP(r1)
3084: 331
332 /* Re-enable interrupts */
3335: ori r10,r10,MSR_EE
334 SYNC
335 MTMSRD(r10)
336
337 andi. r0,r9,_TIF_SAVE_NVGPRS
338 bne save_user_nvgprs
339
340save_user_nvgprs_cont:
341 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
342 beq 7f
343
309 addi r3,r1,STACK_FRAME_OVERHEAD 344 addi r3,r1,STACK_FRAME_OVERHEAD
310 bl do_syscall_trace_leave 345 bl do_syscall_trace_leave
311 REST_NVGPRS(r1) 346 REST_NVGPRS(r1)
3122: 347
313 lwz r3,GPR3(r1) 3486: lwz r3,GPR3(r1)
314 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ 349 LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
315 SYNC 350 SYNC
316 MTMSRD(r10) /* disable interrupts again */ 351 MTMSRD(r10) /* disable interrupts again */
317 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ 352 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
318 lwz r9,TI_FLAGS(r12) 353 lwz r9,TI_FLAGS(r12)
3195: 3547:
320 andi. r0,r9,_TIF_NEED_RESCHED 355 andi. r0,r9,_TIF_NEED_RESCHED
321 bne 1f 356 bne 8f
322 lwz r5,_MSR(r1) 357 lwz r5,_MSR(r1)
323 andi. r5,r5,MSR_PR 358 andi. r5,r5,MSR_PR
324 beq syscall_exit_cont 359 beq ret_from_except
325 andi. r0,r9,_TIF_SIGPENDING 360 andi. r0,r9,_TIF_SIGPENDING
326 beq syscall_exit_cont 361 beq ret_from_except
327 b do_user_signal 362 b do_user_signal
3281: 3638:
329 ori r10,r10,MSR_EE 364 ori r10,r10,MSR_EE
330 SYNC 365 SYNC
331 MTMSRD(r10) /* re-enable interrupts */ 366 MTMSRD(r10) /* re-enable interrupts */
332 bl schedule 367 bl schedule
333 b 2b 368 b 6b
369
370save_user_nvgprs:
371 lwz r8,TI_SIGFRAME(r12)
372
373.macro savewords start, end
374 1: stw \start,4*(\start)(r8)
375 .section __ex_table,"a"
376 .align 2
377 .long 1b,save_user_nvgprs_fault
378 .previous
379 .if \end - \start
380 savewords "(\start+1)",\end
381 .endif
382.endm
383 savewords 14,31
384 b save_user_nvgprs_cont
385
386
387save_user_nvgprs_fault:
388 li r3,11 /* SIGSEGV */
389 lwz r4,TI_TASK(r12)
390 bl force_sigsegv
334 391
392 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
393 lwz r9,TI_FLAGS(r12)
394 b save_user_nvgprs_cont
395
335#ifdef SHOW_SYSCALLS 396#ifdef SHOW_SYSCALLS
336do_show_syscall: 397do_show_syscall:
337#ifdef SHOW_SYSCALLS_TASK 398#ifdef SHOW_SYSCALLS_TASK
@@ -401,28 +462,10 @@ show_syscalls_task:
401#endif /* SHOW_SYSCALLS */ 462#endif /* SHOW_SYSCALLS */
402 463
403/* 464/*
404 * The sigsuspend and rt_sigsuspend system calls can call do_signal 465 * The fork/clone functions need to copy the full register set into
405 * and thus put the process into the stopped state where we might 466 * the child process. Therefore we need to save all the nonvolatile
406 * want to examine its user state with ptrace. Therefore we need 467 * registers (r13 - r31) before calling the C code.
407 * to save all the nonvolatile registers (r13 - r31) before calling
408 * the C code.
409 */ 468 */
410 .globl ppc_sigsuspend
411ppc_sigsuspend:
412 SAVE_NVGPRS(r1)
413 lwz r0,_TRAP(r1)
414 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
415 stw r0,_TRAP(r1) /* register set saved */
416 b sys_sigsuspend
417
418 .globl ppc_rt_sigsuspend
419ppc_rt_sigsuspend:
420 SAVE_NVGPRS(r1)
421 lwz r0,_TRAP(r1)
422 rlwinm r0,r0,0,0,30
423 stw r0,_TRAP(r1)
424 b sys_rt_sigsuspend
425
426 .globl ppc_fork 469 .globl ppc_fork
427ppc_fork: 470ppc_fork:
428 SAVE_NVGPRS(r1) 471 SAVE_NVGPRS(r1)
@@ -447,14 +490,6 @@ ppc_clone:
447 stw r0,_TRAP(r1) /* register set saved */ 490 stw r0,_TRAP(r1) /* register set saved */
448 b sys_clone 491 b sys_clone
449 492
450 .globl ppc_swapcontext
451ppc_swapcontext:
452 SAVE_NVGPRS(r1)
453 lwz r0,_TRAP(r1)
454 rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
455 stw r0,_TRAP(r1) /* register set saved */
456 b sys_swapcontext
457
458/* 493/*
459 * Top-level page fault handling. 494 * Top-level page fault handling.
460 * This is in assembler because if do_page_fault tells us that 495 * This is in assembler because if do_page_fault tells us that
@@ -626,16 +661,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
626 .long ret_from_except 661 .long ret_from_except
627#endif 662#endif
628 663
629 .globl sigreturn_exit
630sigreturn_exit:
631 subi r1,r3,STACK_FRAME_OVERHEAD
632 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
633 lwz r9,TI_FLAGS(r12)
634 andi. r0,r9,_TIF_SYSCALL_T_OR_A
635 beq+ ret_from_except_full
636 bl do_syscall_trace_leave
637 /* fall through */
638
639 .globl ret_from_except_full 664 .globl ret_from_except_full
640ret_from_except_full: 665ret_from_except_full:
641 REST_NVGPRS(r1) 666 REST_NVGPRS(r1)
@@ -658,7 +683,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */
658 /* Check current_thread_info()->flags */ 683 /* Check current_thread_info()->flags */
659 rlwinm r9,r1,0,0,(31-THREAD_SHIFT) 684 rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
660 lwz r9,TI_FLAGS(r9) 685 lwz r9,TI_FLAGS(r9)
661 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED) 686 andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
662 bne do_work 687 bne do_work
663 688
664restore_user: 689restore_user: