*
*/
-#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sys.h>
#include <linux/threads.h>
stw r12,4(r11)
#endif
b 3f
+
2: /* if from kernel, check interrupted DOZE/NAP mode and
* check for stack overflow
*/
+ lwz r9,THREAD_INFO-THREAD(r12)
+ cmplw r1,r9 /* if r1 <= current->thread_info */
+ ble- stack_ovf /* then the kernel stack overflowed */
+5:
#ifdef CONFIG_6xx
- mfspr r11,SPRN_HID0
- mtcr r11
-BEGIN_FTR_SECTION
- bt- 8,power_save_6xx_restore /* Check DOZE */
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
-BEGIN_FTR_SECTION
- bt- 9,power_save_6xx_restore /* Check NAP */
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+ tophys(r9,r9) /* check local flags */
+ lwz r12,TI_LOCAL_FLAGS(r9)
+ mtcrf 0x01,r12
+ bt- 31-TLF_NAPPING,4f
#endif /* CONFIG_6xx */
.globl transfer_to_handler_cont
transfer_to_handler_cont:
- lwz r11,THREAD_INFO-THREAD(r12)
- cmplw r1,r11 /* if r1 <= current->thread_info */
- ble- stack_ovf /* then the kernel stack overflowed */
3:
mflr r9
lwz r11,0(r9) /* virtual address of handler */
lwz r9,4(r9) /* where to go when done */
- FIX_SRR1(r10,r12)
mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r10
mtlr r9
SYNC
RFI /* jump to handler, enable MMU */
+#ifdef CONFIG_6xx
+4: rlwinm r12,r12,0,~_TLF_NAPPING
+ stw r12,TI_LOCAL_FLAGS(r9)
+ b power_save_6xx_restore
+#endif
+
/*
* On kernel stack overflow, load up an initial stack pointer
* and call StackOverflow(regs), which should not return.
*/
stack_ovf:
/* sometimes we use a statically-allocated stack, which is OK. */
- lis r11,_end@h
- ori r11,r11,_end@l
- cmplw r1,r11
- ble 3b /* r1 <= &_end is OK */
+ lis r12,_end@h
+ ori r12,r12,_end@l
+ cmplw r1,r12
+ ble 5b /* r1 <= &_end is OK */
SAVE_NVGPRS(r11)
addi r3,r1,STACK_FRAME_OVERHEAD
lis r1,init_thread_union@ha
0:
_GLOBAL(DoSyscall)
- stw r0,THREAD+LAST_SYSCALL(r2)
stw r3,ORIG_GPR3(r1)
li r12,0
stw r12,RESULT(r1)
MTMSRD(r10)
lwz r9,TI_FLAGS(r12)
li r8,-_LAST_ERRNO
- andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
bne- syscall_exit_work
cmplw 0,r3,r8
blt+ syscall_exit_cont
syscall_exit_work:
andi. r0,r9,_TIF_RESTOREALL
- bne- 2f
- cmplw 0,r3,r8
+ beq+ 0f
+ REST_NVGPRS(r1)
+ b 2f
+0: cmplw 0,r3,r8
blt+ 1f
andi. r0,r9,_TIF_NOERROR
bne- 1f
2: andi. r0,r9,(_TIF_PERSYSCALL_MASK)
beq 4f
- /* Clear per-syscall TIF flags if any are set, but _leave_
- _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that
- yet. */
+ /* Clear per-syscall TIF flags if any are set. */
li r11,_TIF_PERSYSCALL_MASK
addi r12,r12,TI_FLAGS
subi r12,r12,TI_FLAGS
4: /* Anything which requires enabling interrupts? */
- andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS)
- beq 7f
+ andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
+ beq ret_from_except
+
+ /* Re-enable interrupts */
+ ori r10,r10,MSR_EE
+ SYNC
+ MTMSRD(r10)
/* Save NVGPRS if they're not saved already */
lwz r4,_TRAP(r1)
SAVE_NVGPRS(r1)
li r4,0xc00
stw r4,_TRAP(r1)
-
- /* Re-enable interrupts */
-5: ori r10,r10,MSR_EE
- SYNC
- MTMSRD(r10)
-
- andi. r0,r9,_TIF_SAVE_NVGPRS
- bne save_user_nvgprs
-
-save_user_nvgprs_cont:
- andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
- beq 7f
-
+5:
addi r3,r1,STACK_FRAME_OVERHEAD
bl do_syscall_trace_leave
- REST_NVGPRS(r1)
-
-6: lwz r3,GPR3(r1)
- LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
- SYNC
- MTMSRD(r10) /* disable interrupts again */
- rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
- lwz r9,TI_FLAGS(r12)
-7:
- andi. r0,r9,_TIF_NEED_RESCHED
- bne 8f
- lwz r5,_MSR(r1)
- andi. r5,r5,MSR_PR
- beq ret_from_except
- andi. r0,r9,_TIF_SIGPENDING
- beq ret_from_except
- b do_user_signal
-8:
- ori r10,r10,MSR_EE
- SYNC
- MTMSRD(r10) /* re-enable interrupts */
- bl schedule
- b 6b
-
-save_user_nvgprs:
- lwz r8,TI_SIGFRAME(r12)
-
-.macro savewords start, end
- 1: stw \start,4*(\start)(r8)
- .section __ex_table,"a"
- .align 2
- .long 1b,save_user_nvgprs_fault
- .previous
- .if \end - \start
- savewords "(\start+1)",\end
- .endif
-.endm
- savewords 14,31
- b save_user_nvgprs_cont
-
-
-save_user_nvgprs_fault:
- li r3,11 /* SIGSEGV */
- lwz r4,TI_TASK(r12)
- bl force_sigsegv
+ b ret_from_except_full
- rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
- lwz r9,TI_FLAGS(r12)
- b save_user_nvgprs_cont
-
#ifdef SHOW_SYSCALLS
do_show_syscall:
#ifdef SHOW_SYSCALLS_TASK
stw r0,_TRAP(r1) /* register set saved */
b sys_clone
+ .globl ppc_swapcontext
+ppc_swapcontext:
+ SAVE_NVGPRS(r1)
+ lwz r0,_TRAP(r1)
+ rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */
+ stw r0,_TRAP(r1) /* register set saved */
+ b sys_swapcontext
+
/*
* Top-level page fault handling.
* This is in assembler because if do_page_fault tells us that
mr r12,r4 /* restart at exc_exit_restart */
b 2b
- .comm fee_restarts,4
+ .section .bss
+ .align 2
+fee_restarts:
+ .space 4
+ .previous
/* aargh, a nonrecoverable interrupt, panic */
/* aargh, we don't know which trap this is */
/* Check current_thread_info()->flags */
rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
lwz r9,TI_FLAGS(r9)
- andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL)
+ andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
bne do_work
restore_user:
mtspr SPRN_DBSR,r11 /* clear all pending debug events */
blr
- .comm global_dbcr0,8
+ .section .bss
+ .align 4
+global_dbcr0:
+ .space 8
+ .previous
#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
do_work: /* r10 contains MSR_KERNEL here */
lwz r9,TI_FLAGS(r9)
andi. r0,r9,_TIF_NEED_RESCHED
bne- do_resched
- andi. r0,r9,_TIF_SIGPENDING
+ andi. r0,r9,_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK
beq restore_user
do_user_signal: /* r10 contains MSR_KERNEL here */
ori r10,r10,MSR_EE
/* shouldn't return */
b 4b
- .comm ee_restarts,4
+ .section .bss
+ .align 2
+ee_restarts:
+ .space 4
+ .previous
/*
* PROM code for specific machines follows. Put it