diff options
Diffstat (limited to 'arch/openrisc/kernel/entry.S')
| -rw-r--r-- | arch/openrisc/kernel/entry.S | 31 | 
1 files changed, 25 insertions, 6 deletions
| diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index 54a87bba35ca..c9f48e750b72 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -106,6 +106,8 @@  	l.mtspr r0,r3,SPR_EPCR_BASE				;\  	l.lwz   r3,PT_SR(r1)					;\  	l.mtspr r0,r3,SPR_ESR_BASE				;\ +	l.lwz	r3,PT_FPCSR(r1)					;\ +	l.mtspr	r0,r3,SPR_FPCSR					;\  	l.lwz   r2,PT_GPR2(r1)					;\  	l.lwz   r3,PT_GPR3(r1)					;\  	l.lwz   r4,PT_GPR4(r1)					;\ @@ -173,9 +175,10 @@ handler:							;\  	l.sw    PT_GPR28(r1),r28					;\  	l.sw    PT_GPR29(r1),r29					;\  	/* r30 already save */					;\ -/*        l.sw    PT_GPR30(r1),r30*/					;\  	l.sw    PT_GPR31(r1),r31					;\  	TRACE_IRQS_OFF_ENTRY						;\ +	l.mfspr	r30,r0,SPR_FPCSR				;\ +	l.sw	PT_FPCSR(r1),r30				;\  	/* Store -1 in orig_gpr11 for non-syscall exceptions */	;\  	l.addi	r30,r0,-1					;\  	l.sw	PT_ORIG_GPR11(r1),r30 @@ -211,12 +214,13 @@ handler:							;\  	l.sw    PT_GPR27(r1),r27					;\  	l.sw    PT_GPR28(r1),r28					;\  	l.sw    PT_GPR29(r1),r29					;\ -	/* r31 already saved */					;\ -	l.sw    PT_GPR30(r1),r30					;\ -/*        l.sw    PT_GPR31(r1),r31	*/				;\ +	/* r30 already saved */						;\ +	l.sw    PT_GPR31(r1),r31					;\  	/* Store -1 in orig_gpr11 for non-syscall exceptions */	;\  	l.addi	r30,r0,-1					;\  	l.sw	PT_ORIG_GPR11(r1),r30				;\ +	l.mfspr	r30,r0,SPR_FPCSR				;\ +	l.sw	PT_FPCSR(r1),r30				;\  	l.addi	r3,r1,0						;\  	/* r4 is exception EA */				;\  	l.addi	r5,r0,vector					;\ @@ -844,9 +848,16 @@ _syscall_badsys:  /******* END SYSCALL HANDLING *******/ -/* ---[ 0xd00: Trap exception ]------------------------------------------ */ +/* ---[ 0xd00: Floating Point exception ]-------------------------------- */ -UNHANDLED_EXCEPTION(_vector_0xd00,0xd00) +EXCEPTION_ENTRY(_fpe_trap_handler) +	CLEAR_LWA_FLAG(r3) +	/* r4: EA of fault (set by EXCEPTION_HANDLE) */ +	l.jal   do_fpe_trap +	 l.addi  r3,r1,0 /* pt_regs */ + +	l.j     _ret_from_exception +	 l.nop  /* ---[ 0xe00: Trap exception ]------------------------------------------ */ @@ -1089,6 +1100,10 @@ ENTRY(_switch)  	l.sw    PT_GPR28(r1),r28  	l.sw    PT_GPR30(r1),r30 +	/* Store the old FPU state to new pt_regs */ +	l.mfspr	r29,r0,SPR_FPCSR +	l.sw	PT_FPCSR(r1),r29 +  	l.addi	r11,r10,0			/* Save old 'current' to 'last' return value*/  	/* We use thread_info->ksp for storing the address of the above @@ -1111,6 +1126,10 @@ ENTRY(_switch)  	l.lwz	r29,PT_SP(r1)  	l.sw	TI_KSP(r10),r29 +	/* Restore the old value of FPCSR */ +	l.lwz	r29,PT_FPCSR(r1) +	l.mtspr	r0,r29,SPR_FPCSR +  	/* ...and restore the registers, except r11 because the return value  	 * has already been set above.  	 */ | 
