Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c138e12f authored by Atsushi Nemoto's avatar Atsushi Nemoto Committed by Ralf Baechle
Browse files

[MIPS] Fix fpu_save_double on 64-bit.



> Without this fix, _save_fp() in 64-bit kernel is seriously broken.
>
> ffffffff8010bec0 <_save_fp>:
> ffffffff8010bec0:       400d6000        mfc0    t1,c0_status
> ffffffff8010bec4:       000c7140        sll     t2,t0,0x5
> ffffffff8010bec8:       05c10011        bgez    t2,ffffffff8010bf10 <_save_fp+0x50>
> ffffffff8010becc:       00000000        nop
> ffffffff8010bed0:       f4810328        sdc1    $f1,808(a0)
> ...

Fix register usage in fpu_save_double() and make fpu_restore_double()
more symmetric with fpu_save_double().

Signed-off-by: default avatarAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 73499682
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -75,8 +75,8 @@
	and	t0, t0, t1
	LONG_S	t0, ST_OFF(t3)

	fpu_save_double a0 t1 t0 t2		# c0_status passed in t1
						# clobbers t0 and t2
	fpu_save_double a0 t0 t1		# c0_status passed in t0
						# clobbers t1
1:

	/*
@@ -129,9 +129,9 @@
 */
LEAF(_save_fp)
#ifdef CONFIG_64BIT
	mfc0	t1, CP0_STATUS
	mfc0	t0, CP0_STATUS
#endif
	fpu_save_double a0 t1 t0 t2		# clobbers t1
	fpu_save_double a0 t0 t1		# clobbers t1
	jr	ra
	END(_save_fp)

@@ -139,7 +139,10 @@ LEAF(_save_fp)
 * Restore a thread's fp context.
 */
LEAF(_restore_fp)
	fpu_restore_double a0, t1		# clobbers t1
#ifdef CONFIG_64BIT
	mfc0	t0, CP0_STATUS
#endif
	fpu_restore_double a0 t0 t1		# clobbers t1
	jr	ra
	END(_restore_fp)

+2 −2
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>

	.macro	fpu_save_double thread status tmp1=t0 tmp2
	.macro	fpu_save_double thread status tmp1=t0
	cfc1	\tmp1,  fcr31
	sdc1	$f0,  THREAD_FPR0(\thread)
	sdc1	$f2,  THREAD_FPR2(\thread)
@@ -70,7 +70,7 @@
	sw	\tmp, THREAD_FCR31(\thread)
	.endm

	.macro	fpu_restore_double thread tmp=t0
	.macro	fpu_restore_double thread status tmp=t0
	lw	\tmp, THREAD_FCR31(\thread)
	ldc1	$f0,  THREAD_FPR0(\thread)
	ldc1	$f2,  THREAD_FPR2(\thread)
+9 −10
Original line number Diff line number Diff line
@@ -53,12 +53,12 @@
	sdc1	$f31, THREAD_FPR31(\thread)
	.endm

	.macro	fpu_save_double thread status tmp1 tmp2
	sll	\tmp2, \tmp1, 5
	bgez	\tmp2, 2f
	.macro	fpu_save_double thread status tmp
	sll	\tmp, \status, 5
	bgez	\tmp, 2f
	fpu_save_16odd \thread
2:
	fpu_save_16even \thread \tmp1			# clobbers t1
	fpu_save_16even \thread \tmp
	.endm

	.macro	fpu_restore_16even thread tmp=t0
@@ -101,13 +101,12 @@
	ldc1	$f31, THREAD_FPR31(\thread)
	.endm

	.macro	fpu_restore_double thread tmp
	mfc0	t0, CP0_STATUS
	sll	t1, t0, 5
	bgez	t1, 1f				# 16 register mode?
	.macro	fpu_restore_double thread status tmp
	sll	\tmp, \status, 5
	bgez	\tmp, 1f				# 16 register mode?

	fpu_restore_16odd a0
1:	fpu_restore_16even a0, t0		# clobbers t0
	fpu_restore_16odd \thread
1:	fpu_restore_16even \thread \tmp
	.endm

	.macro	cpu_save_nonscratch thread