X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fkernel%2Fentry.S;h=08083be4c6abba68cc161e0cd9943973c43d3a3d;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=8108917eaa5cb931ced837859266d15ef86baaa3;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 8108917ea..08083be4c 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -36,7 +36,7 @@ #undef SHOW_SYSCALLS_TASK /* - * MSR_KERNEL is > 0x10000 on 4xx since it include MSR_CE. + * MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE. */ #if MSR_KERNEL >= 0x10000 #define LOAD_MSR_KERNEL(r, x) lis r,(x)@h; ori r,r,(x)@l @@ -45,7 +45,7 @@ #endif #ifdef CONFIG_BOOKE -#define COR r8 +#define COR r8 /* Critical Offset Register (COR) */ #define BOOKE_LOAD_COR lis COR,crit_save@ha #define BOOKE_REST_COR mfspr COR,SPRG2 #define BOOKE_SAVE_COR mtspr SPRG2,COR @@ -111,8 +111,10 @@ transfer_to_handler: addi r11,r1,STACK_FRAME_OVERHEAD stw r11,PT_REGS(r12) #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) - lwz r12,PTRACE-THREAD(r12) - andi. r12,r12,PT_PTRACED + /* Check to see if the dbcr0 register is set up to debug. Use the + single-step bit to do this. */ + lwz r12,THREAD_DBCR0(r12) + andis. r12,r12,DBCR0_IC@h beq+ 3f /* From user and task is ptraced - load up global dbcr0 */ li r12,-1 /* clear all pending debug events */ @@ -206,7 +208,7 @@ _GLOBAL(DoSyscall) andi. r11,r11,_TIF_SYSCALL_TRACE bne- syscall_dotrace syscall_dotrace_cont: - cmpli 0,r0,NR_syscalls + cmplwi 0,r0,NR_syscalls lis r10,sys_call_table@h ori r10,r10,sys_call_table@l slwi r0,r0,2 @@ -222,7 +224,7 @@ ret_from_syscall: #endif mr r6,r3 li r11,-_LAST_ERRNO - cmpl 0,r3,r11 + cmplw 0,r3,r11 rlwinm r12,r1,0,0,18 /* current_thread_info() */ blt+ 30f lwz r11,TI_LOCAL_FLAGS(r12) @@ -241,11 +243,12 @@ ret_from_syscall: andi. r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne- syscall_exit_work syscall_exit_cont: -#ifdef CONFIG_4xx - /* If the process has its own DBCR0 value, load it up */ - lwz r0,PTRACE(r2) - andi. r0,r0,PT_PTRACED - bnel- load_4xx_dbcr0 +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + /* If the process has its own DBCR0 value, load it up. The single + step bit tells us that dbcr0 should be loaded. */ + lwz r0,THREAD+THREAD_DBCR0(r2) + andis. r10,r0,DBCR0_IC@h + bnel- load_dbcr0 #endif stwcx. r0,0,r1 /* to clear the reservation */ lwz r4,_LINK(r1) @@ -510,7 +513,12 @@ BEGIN_FTR_SECTION stw r12,THREAD+THREAD_VRSAVE(r2) END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ - and. r0,r0,r11 /* FP or altivec enabled? */ +#ifdef CONFIG_SPE + oris r0,r0,MSR_SPE@h /* Disable SPE */ + mfspr r12,SPRN_SPEFSCR /* save spefscr register value */ + stw r12,THREAD+THREAD_SPEFSCR(r2) +#endif /* CONFIG_SPE */ + and. r0,r0,r11 /* FP or altivec or SPE enabled? */ beq+ 1f andc r11,r11,r0 MTMSRD(r11) @@ -543,6 +551,10 @@ BEGIN_FTR_SECTION mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + lwz r0,THREAD+THREAD_SPEFSCR(r2) + mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */ +#endif /* CONFIG_SPE */ lwz r0,_CCR(r1) mtcrf 0xFF,r0 @@ -589,11 +601,12 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ bne do_work restore_user: -#ifdef CONFIG_4xx - /* Check whether this process has its own DBCR0 value */ - lwz r0,PTRACE(r2) - andi. r0,r0,PT_PTRACED - bnel- load_4xx_dbcr0 +#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) + /* Check whether this process has its own DBCR0 value. The single + step bit tells us that dbcr0 should be loaded. */ + lwz r0,THREAD+THREAD_DBCR0(r2) + andis. r10,r0,DBCR0_IC@h + bnel- load_dbcr0 #endif #ifdef CONFIG_PREEMPT @@ -611,18 +624,8 @@ resume_kernel: beq+ restore andi. r0,r3,MSR_EE /* interrupts off? */ beq restore /* don't schedule if so */ -1: lis r0,PREEMPT_ACTIVE@h - stw r0,TI_PREEMPT(r9) - ori r10,r10,MSR_EE - SYNC - MTMSRD(r10) /* hard-enable interrupts */ - bl schedule - LOAD_MSR_KERNEL(r10,MSR_KERNEL) - SYNC - MTMSRD(r10) /* disable interrupts */ +1: bl preempt_schedule_irq rlwinm r9,r1,0,0,18 - li r0,0 - stw r0,TI_PREEMPT(r9) lwz r3,TI_FLAGS(r9) andi. r0,r3,_TIF_NEED_RESCHED bne- 1b @@ -645,7 +648,7 @@ restore: PPC405_ERR77(0,r1) stwcx. r0,0,r1 /* to clear the reservation */ -#ifndef CONFIG_4xx +#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) lwz r9,_MSR(r1) andi. r10,r9,MSR_RI /* check if this exception occurred */ beql nonrecoverable /* at a bad place (MSR:RI = 0) */ @@ -681,9 +684,9 @@ exc_exit_restart_end: SYNC RFI -#else /* CONFIG_4xx */ +#else /* !(CONFIG_4xx || CONFIG_BOOKE) */ /* - * This is a bit different on 4xx because 4xx doesn't have + * This is a bit different on 4xx/Book-E because it doesn't have * the RI bit in the MSR. * The TLB miss handler checks if we have interrupted * the exception exit path and restarts it if so @@ -720,6 +723,9 @@ exc_exit_restart_end: * give the wrong answer). * We have to restore various SPRs that may have been in use at the * time of the critical interrupt. + * + * Note that SPRG6 is used for machine check on CONFIG_BOOKE parts and + * thus not saved in the critical handler */ .globl ret_from_crit_exc ret_from_crit_exc: @@ -864,17 +870,17 @@ ret_from_mcheck_exc: /* * Load the DBCR0 value for a task that is being ptraced, - * having first saved away the global DBCR0. + * having first saved away the global DBCR0. Note that r0 + * has the dbcr0 value to set upon entry to this. */ -load_4xx_dbcr0: - mfmsr r0 /* first disable debug exceptions */ - rlwinm r0,r0,0,~MSR_DE - mtmsr r0 +load_dbcr0: + mfmsr r10 /* first disable debug exceptions */ + rlwinm r10,r10,0,~MSR_DE + mtmsr r10 isync mfspr r10,SPRN_DBCR0 lis r11,global_dbcr0@ha addi r11,r11,global_dbcr0@l - lwz r0,THREAD+THREAD_DBCR0(r2) stw r10,0(r11) mtspr SPRN_DBCR0,r0 lwz r10,4(r11) @@ -885,7 +891,7 @@ load_4xx_dbcr0: blr .comm global_dbcr0,8 -#endif /* CONFIG_4xx */ +#endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ do_work: /* r10 contains MSR_KERNEL here */ andi. r0,r9,_TIF_NEED_RESCHED